diff --git a/rtdata/languages/default b/rtdata/languages/default index 64391b656..1ae3dafde 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -457,6 +457,10 @@ HISTORY_MSG_248;'HH' curve HISTORY_MSG_249;CbDL - Threshold HISTORY_MSG_250;NR - Enhanced HISTORY_MSG_251;B&W - Algorithm +HISTORY_MSG_252;CbDL Skin Tones +HISTORY_MSG_253;CbDL Reduce artifacts +HISTORY_MSG_254;CbDL - Hueskin +HISTORY_MSG_255;CbDL - Algorithm HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1075,6 +1079,16 @@ TP_DIRPYREQUALIZER_LUMACONTRAST_PLUS;Contrast+ TP_DIRPYREQUALIZER_LUMAFINEST;Finest TP_DIRPYREQUALIZER_LUMANEUTRAL;Neutral TP_DIRPYREQUALIZER_THRESHOLD;Threshold +TP_DIRPYREQUALIZER_ALGO;Algorithm Skin +TP_DIRPYREQUALIZER_ALGO_FI;Fine +TP_DIRPYREQUALIZER_ALGO_LA;Large +TP_DIRPYREQUALIZER_ALGO_TOOLTIP;Fine: closer to the colors of the skin, minimizing the action on other colors\nLarge: avoid more artifacts +TP_DIRPYREQUALIZER_SKIN;Skin Tones Targetting/Protection +TP_DIRPYREQUALIZER_SKIN_TOOLTIP;At -100 skin tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin tones are protected while all other tones are affected. +TP_DIRPYREQUALIZER_HUESKIN;Skin hue +TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP;This pyramid is for the upper part, so far as the algorithm at its maximum efficiency.\nTo the lower part, the transition zones.\nIf you need to move the area significantly to the left or right - or if there are artifacts: the white balance is incorrect\nYou can slightly reduce the zone to prevent the rest of the image is affected +TP_DIRPYREQUALIZER_GAMUT;Reduce artifacts +TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts due to the transitions between the color (hue, chroma, luma) of the skin and the rest of the image TP_DISTORTION_AMOUNT;Amount TP_DISTORTION_AUTO;Auto Distortion Correction TP_DISTORTION_AUTO_TIP;Correct lens distortion automatically for some cameras (Micro 4/3, some compact digital cameras, etc.). diff --git a/rtdata/profiles/BW/BW 1.pp3 b/rtdata/profiles/BW/BW 1.pp3 index 5bf45c484..2cabb35bf 100644 --- a/rtdata/profiles/BW/BW 1.pp3 +++ b/rtdata/profiles/BW/BW 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/BW/BW 2.pp3 b/rtdata/profiles/BW/BW 2.pp3 index 76d9a1673..27fb098fd 100644 --- a/rtdata/profiles/BW/BW 2.pp3 +++ b/rtdata/profiles/BW/BW 2.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/BW/BW 3.pp3 b/rtdata/profiles/BW/BW 3.pp3 index 298d85afe..445dd7ad8 100644 --- a/rtdata/profiles/BW/BW 3.pp3 +++ b/rtdata/profiles/BW/BW 3.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/BW/BW 4.pp3 b/rtdata/profiles/BW/BW 4.pp3 index bb857c5e6..93b15b27b 100644 --- a/rtdata/profiles/BW/BW 4.pp3 +++ b/rtdata/profiles/BW/BW 4.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Default ISO High.pp3 b/rtdata/profiles/Default ISO High.pp3 index a7cc7e444..55375af34 100644 --- a/rtdata/profiles/Default ISO High.pp3 +++ b/rtdata/profiles/Default ISO High.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Default ISO Medium.pp3 b/rtdata/profiles/Default ISO Medium.pp3 index 333769c02..fb9b67a41 100644 --- a/rtdata/profiles/Default ISO Medium.pp3 +++ b/rtdata/profiles/Default ISO Medium.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Default.pp3 b/rtdata/profiles/Default.pp3 index f016a4bef..123860247 100644 --- a/rtdata/profiles/Default.pp3 +++ b/rtdata/profiles/Default.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 index 8fa7f8395..78f681063 100644 --- a/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Amber 1 TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 b/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 index 364620bf0..216339b4e 100644 --- a/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 +++ b/rtdata/profiles/Faded/Faded Amber 1 TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Amber 1.pp3 b/rtdata/profiles/Faded/Faded Amber 1.pp3 index c3be435a9..9c696db84 100644 --- a/rtdata/profiles/Faded/Faded Amber 1.pp3 +++ b/rtdata/profiles/Faded/Faded Amber 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 index a0f58aa10..38ae1c1e6 100644 --- a/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Blue 1 TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 b/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 index f76e7aecf..4cc197dc9 100644 --- a/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 +++ b/rtdata/profiles/Faded/Faded Blue 1 TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Blue 1.pp3 b/rtdata/profiles/Faded/Faded Blue 1.pp3 index f57039519..3359c1c50 100644 --- a/rtdata/profiles/Faded/Faded Blue 1.pp3 +++ b/rtdata/profiles/Faded/Faded Blue 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 b/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 index 9fefe9ab4..93c6eb447 100644 --- a/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 +++ b/rtdata/profiles/Faded/Faded Blue Pink TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Blue Pink.pp3 b/rtdata/profiles/Faded/Faded Blue Pink.pp3 index 231f1ec31..c87a75f83 100644 --- a/rtdata/profiles/Faded/Faded Blue Pink.pp3 +++ b/rtdata/profiles/Faded/Faded Blue Pink.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 index 58b29c1d6..a6378877f 100644 --- a/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Chocolate 1 TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 index 1d03207bc..71af0eaf5 100644 --- a/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Chocolate 2 TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Golden 1.pp3 b/rtdata/profiles/Faded/Faded Golden 1.pp3 index 73dc7cbc9..a03b19077 100644 --- a/rtdata/profiles/Faded/Faded Golden 1.pp3 +++ b/rtdata/profiles/Faded/Faded Golden 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Golden 2.pp3 b/rtdata/profiles/Faded/Faded Golden 2.pp3 index 5f76b4aec..790348d73 100644 --- a/rtdata/profiles/Faded/Faded Golden 2.pp3 +++ b/rtdata/profiles/Faded/Faded Golden 2.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 index fad2ce408..490d38410 100644 --- a/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Green 1 TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Green 1 TM.pp3 b/rtdata/profiles/Faded/Faded Green 1 TM.pp3 index 74e4656ec..1ad37389c 100644 --- a/rtdata/profiles/Faded/Faded Green 1 TM.pp3 +++ b/rtdata/profiles/Faded/Faded Green 1 TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Green 1.pp3 b/rtdata/profiles/Faded/Faded Green 1.pp3 index 2f0e7386d..776996fd7 100644 --- a/rtdata/profiles/Faded/Faded Green 1.pp3 +++ b/rtdata/profiles/Faded/Faded Green 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Green 2.pp3 b/rtdata/profiles/Faded/Faded Green 2.pp3 index 4a377328c..916a89b76 100644 --- a/rtdata/profiles/Faded/Faded Green 2.pp3 +++ b/rtdata/profiles/Faded/Faded Green 2.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Green 3.pp3 b/rtdata/profiles/Faded/Faded Green 3.pp3 index 9b7babee4..868a646e3 100644 --- a/rtdata/profiles/Faded/Faded Green 3.pp3 +++ b/rtdata/profiles/Faded/Faded Green 3.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Neutral TM.pp3 b/rtdata/profiles/Faded/Faded Neutral TM.pp3 index 64d99890b..54d2d04bd 100644 --- a/rtdata/profiles/Faded/Faded Neutral TM.pp3 +++ b/rtdata/profiles/Faded/Faded Neutral TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Neutral.pp3 b/rtdata/profiles/Faded/Faded Neutral.pp3 index 3dae8d760..91309a946 100644 --- a/rtdata/profiles/Faded/Faded Neutral.pp3 +++ b/rtdata/profiles/Faded/Faded Neutral.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 index 53b69871a..cb96611ac 100644 --- a/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Purple 1 TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 b/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 index 3ecb0c6a5..a9eb8d476 100644 --- a/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 +++ b/rtdata/profiles/Faded/Faded Purple 1 TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Purple 1.pp3 b/rtdata/profiles/Faded/Faded Purple 1.pp3 index 21be1473d..c63e6ab80 100644 --- a/rtdata/profiles/Faded/Faded Purple 1.pp3 +++ b/rtdata/profiles/Faded/Faded Purple 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 b/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 index 767534268..4e50aebde 100644 --- a/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 +++ b/rtdata/profiles/Faded/Faded Purple 2 TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Purple 2.pp3 b/rtdata/profiles/Faded/Faded Purple 2.pp3 index 5411da102..a18353b85 100644 --- a/rtdata/profiles/Faded/Faded Purple 2.pp3 +++ b/rtdata/profiles/Faded/Faded Purple 2.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 b/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 index a623115d0..1f44d5019 100644 --- a/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Teal Orange TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 b/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 index 663810358..c695aba73 100644 --- a/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 +++ b/rtdata/profiles/Faded/Faded Teal Orange TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Teal Orange.pp3 b/rtdata/profiles/Faded/Faded Teal Orange.pp3 index fec0b7a61..be2fcb653 100644 --- a/rtdata/profiles/Faded/Faded Teal Orange.pp3 +++ b/rtdata/profiles/Faded/Faded Teal Orange.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 b/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 index f3ac4cbc8..37403818a 100644 --- a/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 +++ b/rtdata/profiles/Faded/Faded Warm 1 TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 b/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 index 7553be623..9e4aa4507 100644 --- a/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 +++ b/rtdata/profiles/Faded/Faded Warm 1 TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Warm 1.pp3 b/rtdata/profiles/Faded/Faded Warm 1.pp3 index 5043341ef..ea42493a7 100644 --- a/rtdata/profiles/Faded/Faded Warm 1.pp3 +++ b/rtdata/profiles/Faded/Faded Warm 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Warm 2.pp3 b/rtdata/profiles/Faded/Faded Warm 2.pp3 index 092e24444..b62355b51 100644 --- a/rtdata/profiles/Faded/Faded Warm 2.pp3 +++ b/rtdata/profiles/Faded/Faded Warm 2.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Faded/Faded Warm 3.pp3 b/rtdata/profiles/Faded/Faded Warm 3.pp3 index 934d37026..063eb8be6 100644 --- a/rtdata/profiles/Faded/Faded Warm 3.pp3 +++ b/rtdata/profiles/Faded/Faded Warm 3.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=315 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Generic/Deep Shadows.pp3 b/rtdata/profiles/Generic/Deep Shadows.pp3 index f89e79de8..416cead89 100644 --- a/rtdata/profiles/Generic/Deep Shadows.pp3 +++ b/rtdata/profiles/Generic/Deep Shadows.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Generic/Equilibrated.pp3 b/rtdata/profiles/Generic/Equilibrated.pp3 index c82bf3132..8c8e787a9 100644 --- a/rtdata/profiles/Generic/Equilibrated.pp3 +++ b/rtdata/profiles/Generic/Equilibrated.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Generic/High-Key.pp3 b/rtdata/profiles/Generic/High-Key.pp3 index 383ce620b..c8351a292 100644 --- a/rtdata/profiles/Generic/High-Key.pp3 +++ b/rtdata/profiles/Generic/High-Key.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Generic/Natural 1.pp3 b/rtdata/profiles/Generic/Natural 1.pp3 index be36dd176..5f90d9fe7 100644 --- a/rtdata/profiles/Generic/Natural 1.pp3 +++ b/rtdata/profiles/Generic/Natural 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Generic/Natural 2.pp3 b/rtdata/profiles/Generic/Natural 2.pp3 index a9bb31a14..b621535f9 100644 --- a/rtdata/profiles/Generic/Natural 2.pp3 +++ b/rtdata/profiles/Generic/Natural 2.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Generic/Punchy 1.pp3 b/rtdata/profiles/Generic/Punchy 1.pp3 index c0bea7690..e7bd9df08 100644 --- a/rtdata/profiles/Generic/Punchy 1.pp3 +++ b/rtdata/profiles/Generic/Punchy 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Generic/Punchy 2.pp3 b/rtdata/profiles/Generic/Punchy 2.pp3 index d13fdf2e0..a14e0e7f5 100644 --- a/rtdata/profiles/Generic/Punchy 2.pp3 +++ b/rtdata/profiles/Generic/Punchy 2.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=true diff --git a/rtdata/profiles/Pop/Pop 1.pp3 b/rtdata/profiles/Pop/Pop 1.pp3 index db5ab2ca2..de7977994 100644 --- a/rtdata/profiles/Pop/Pop 1.pp3 +++ b/rtdata/profiles/Pop/Pop 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Pop/Pop 2 L.pp3 b/rtdata/profiles/Pop/Pop 2 L.pp3 index 5fe168961..a838af63b 100644 --- a/rtdata/profiles/Pop/Pop 2 L.pp3 +++ b/rtdata/profiles/Pop/Pop 2 L.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Pop/Pop 3 Skin.pp3 b/rtdata/profiles/Pop/Pop 3 Skin.pp3 index 0d3ebb219..539cbacab 100644 --- a/rtdata/profiles/Pop/Pop 3 Skin.pp3 +++ b/rtdata/profiles/Pop/Pop 3 Skin.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Pop/Pop 4 BW.pp3 b/rtdata/profiles/Pop/Pop 4 BW.pp3 index 6cab448d5..3796d8880 100644 --- a/rtdata/profiles/Pop/Pop 4 BW.pp3 +++ b/rtdata/profiles/Pop/Pop 4 BW.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Portrait/Portrait Lejto.pp3 b/rtdata/profiles/Portrait/Portrait Lejto.pp3 index ffd7b0d91..e923734e9 100644 --- a/rtdata/profiles/Portrait/Portrait Lejto.pp3 +++ b/rtdata/profiles/Portrait/Portrait Lejto.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Portrait/Portrait Smooth.pp3 b/rtdata/profiles/Portrait/Portrait Smooth.pp3 index c75460ca6..2392d5a54 100644 --- a/rtdata/profiles/Portrait/Portrait Smooth.pp3 +++ b/rtdata/profiles/Portrait/Portrait Smooth.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 b/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 index dd150ab3b..13ff341a4 100644 --- a/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Natural TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Natural.pp3 b/rtdata/profiles/Skintones/Skintones - Natural.pp3 index 3b5ccbdf8..7419c29d5 100644 --- a/rtdata/profiles/Skintones/Skintones - Natural.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Natural.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 b/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 index 36bff3799..791b429aa 100644 --- a/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Pale TM Bright.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 b/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 index c21044dcf..bd9fd36a9 100644 --- a/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Pale TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Pale.pp3 b/rtdata/profiles/Skintones/Skintones - Pale.pp3 index 8c4e2a30b..a95b5cb64 100644 --- a/rtdata/profiles/Skintones/Skintones - Pale.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Pale.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 b/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 index 9bd28674b..7195fba6c 100644 --- a/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Soft Texture.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 b/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 index 83e9e8f90..a663bdc0b 100644 --- a/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Strong Texture.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 b/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 index 27bb6a77c..c4944c06a 100644 --- a/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Studio TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - Studio.pp3 b/rtdata/profiles/Skintones/Skintones - Studio.pp3 index e9d5e68aa..489a81419 100644 --- a/rtdata/profiles/Skintones/Skintones - Studio.pp3 +++ b/rtdata/profiles/Skintones/Skintones - Studio.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 b/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 index ad2b2ec9d..48423a585 100644 --- a/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 +++ b/rtdata/profiles/Skintones/Skintones - StudioBase 1 TM.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 b/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 index 208fdb7ef..d8b947a15 100644 --- a/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 +++ b/rtdata/profiles/Skintones/Skintones - StudioBase 1.pp3 @@ -1,6 +1,6 @@ [Version] AppVersion=4.0.12 -Version=316 +Version=319 [Exposure] Auto=false diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc index 9e438b349..5d884cda0 100644 --- a/rtengine/PF_correct_RT.cc +++ b/rtengine/PF_correct_RT.cc @@ -593,9 +593,9 @@ PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median #if defined( __SSE2__ ) && defined( WIN32 ) -__attribute__((force_align_arg_pointer)) void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad) #else -void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode) +void ImProcFunctions::Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad) #endif { const int halfwin = ceil(2*radius)+1; @@ -1011,6 +1011,7 @@ float chrommed=0.f; #pragma omp for #endif for(int i = 0; i < height; i++ ) { +/* #ifdef __SSE2__ for(j = 0; j < width-3; j+=4) { interav = LVFU(tmaa[i][j]); @@ -1025,13 +1026,23 @@ float chrommed=0.f; dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); } #else +*/ for(int j = 0; j < width; j++) { float intera = tmaa[i][j]; float interb = tmbb[i][j]; + float CC=sqrt(SQR(interb)+SQR(intera)); + if(hotbad==0) { + if(CC < chrom && skinprot !=0.f){ dst->h_p[i][j]=(xatan2f(interb,intera))/piid; dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } + } + else { + dst->h_p[i][j]=(xatan2f(interb,intera))/piid; + dst->C_p[i][j]=sqrt(SQR(interb)+SQR(intera)); + } } -#endif +//#endif } } @@ -1070,6 +1081,500 @@ float chrommed=0.f; } + + +#if defined( __SSE2__ ) && defined( WIN32 ) +__attribute__((force_align_arg_pointer)) void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom) +#else +void ImProcFunctions::BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom) +#endif +{ + const int halfwin = ceil(2*radius)+1; + MyTime t1,t2; + t1.set(); + + const int width=src->W, height=src->H; +// const float piid=3.14159265f/180.f; + float shfabs, shmed; + + int i1, j1, tot; + const float eps = 1.0f; + const float eps2 = 0.01f; + float shsum, dirsh, norm, sum; + + float** sraa; + sraa = new float*[height]; + for (int i=0; ia[i][j])); + _mm_storeu_ps(&srbb[i][j],LVFU(src->b[i][j])); + } + for (; ja[i][j]; + srbb[i][j]=src->b[i][j]; + } +#else + for (int j=0; ja[i][j]; + srbb[i][j]=src->b[i][j]; + } +#endif + } +} + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBufferMP buffer(max(src->W,src->H)); + //chroma a and b + if(mode>=2) {//choice of gaussian blur + gaussHorizontal (sraa, tmaa, buffer, src->W, src->H, radius); + gaussHorizontal (srbb, tmbb, buffer, src->W, src->H, radius); + gaussVertical (tmaa, tmaa, buffer, src->W, src->H, radius); + gaussVertical (tmbb, tmbb, buffer, src->W, src->H, radius); + } + //luma sh_p + gaussHorizontal (src->L, tmL, buffer, src->W, src->H, 2.0);//low value to avoid artifacts + gaussVertical (tmL, tmL, buffer, src->W, src->H, 2.0); + } + +if(mode==1){ //choice of median +#pragma omp parallel + { + int ip,in,jp,jn; + float pp[9],temp; +#pragma omp for nowait //nowait because next loop inside this parallel region is independent on this one + for (int i=0; iheight-3) {in=i-2;} else {in=i+2;} + for (int j=0; jwidth-3) {jn=j-2;} else {jn=j+2;} + med3(sraa[ip][jp],sraa[ip][j],sraa[ip][jn],sraa[i][jp],sraa[i][j],sraa[i][jn],sraa[in][jp],sraa[in][j],sraa[in][jn],tmaa[i][j]); + } + } +#pragma omp for + for (int i=0; iheight-3) {in=i-2;} else {in=i+2;} + for (int j=0; jwidth-3) {jn=j-2;} else {jn=j+2;} + med3(srbb[ip][jp],srbb[ip][j],srbb[ip][jn],srbb[i][jp],srbb[i][j],srbb[i][jn],srbb[in][jp],srbb[in][j],srbb[in][jn],tmbb[i][j]); + } + } + } +} + +//luma badpixels + const float sh_thr = 4.5f;//low value for luma sh_p to avoid artifacts + const float shthr = sh_thr / 24.0f; + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; +#ifdef __SSE2__ + __m128 shfabsv, shmedv; + __m128 shthrv = _mm_set1_ps(shthr); + __m128 onev = _mm_set1_ps(1.0f); +#endif // __SSE2__ +#ifdef _OPENMP +#pragma omp for private(shfabs, shmed,i1,j1) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + shmed += fabs(src->L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } + +#ifdef __SSE2__ + for (; j < width-5; j+=4) { + shfabsv = vabsf(LVFU(src->L[i][j])-LVFU(tmL[i][j])); + shmedv = _mm_setzero_ps(); + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmedv += vabsf(LVFU(src->L[i1][j1])-LVFU(tmL[i1][j1])); + } + _mm_storeu_ps( &badpix[i*width+j], vself(vmaskf_gt(shfabsv,(shmedv - shfabsv)*shthrv), onev, _mm_setzero_ps())); + } + for (; j < width-2; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmed += fabs(src->L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } +#else + for (; j < width-2; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + shmed += fabs(src->L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } +#endif + for (; j < width; j++) { + shfabs = fabs(src->L[i][j]-tmL[i][j]); + shmed=0.0f; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1L[i1][j1]-tmL[i1][j1]); + } + badpix[i*width+j] = (shfabs>((shmed-shfabs)*shthr)); + } + } +} + + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; +#ifdef _OPENMP +#pragma omp for private(shsum,norm,dirsh,sum,i1,j1) schedule(dynamic,16) +#endif + for (int i=0; i < height; i++) { + for (j=0; j < 2; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=0; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (badpix[i1*width+j1]) continue; + sum += src->L[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->L[i1][j1]-src->L[i][j])+eps); + shsum += dirsh*src->L[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->L[i][j]=shsum/norm; + } + else { + if(tot > 0) src->L[i][j]=sum / tot; + } + } + for (; j < width-2; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1<=j+2; j1++ ) { + if (i1==i && j1==j) continue; + if (badpix[i1*width+j1]) continue; + sum += src->L[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->L[i1][j1]-src->L[i][j])+eps); + shsum += dirsh*src->L[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->L[i][j]=shsum/norm; + } + else { + if(tot > 0) src->L[i][j]=sum / tot; + } + } + for (; j < width; j++) { + if (!badpix[i*width+j]) continue; + norm=0.0f; + shsum=0.0f; + sum=0.0f; + tot=0; + for (i1=max(0,i-2); i1<=min(i+2,height-1); i1++ ) + for (j1=j-2; j1L[i1][j1]; + tot++; + dirsh = 1.f/(SQR(src->L[i1][j1]-src->L[i][j])+eps); + shsum += dirsh*src->L[i1][j1]; + norm += dirsh; + } + if (norm > 0.f) { + src->L[i][j]=shsum/norm; + } + else { + if(tot > 0) src->L[i][j]=sum / tot; + } + } + } +} +// end luma badpixels + +if(mode==3) { +// begin chroma badpixels +float chrommed=0.f; +#ifdef _OPENMP +#pragma omp parallel for reduction(+:chrommed) +#endif + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + float chroma =SQR(sraa[i][j]-tmaa[i][j])+SQR(srbb[i][j]-tmbb[i][j]); + chrommed += chroma; + badpix[i*width+j]=chroma; + } + } + chrommed /= (height*width); + float threshfactor = (thresh*chrommed)/33.f; + +// now chrommed is calculated, so we postprocess badpix to reduce the number of divisions in future +#ifdef __SSE2__ +#ifdef _OPENMP +#pragma omp parallel +#endif +{ + int j; + __m128 sumv = _mm_set1_ps( chrommed + eps2 ); + __m128 onev = _mm_set1_ps( 1.0f ); +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width-halfwin; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (badpix[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + for(; j < width; j++) { + tmaa[i][j] = sraa[i][j]; + tmbb[i][j] = srbb[i][j]; + + if (badpix[i*width+j] 0.f){ + tmaa[i][j] = (atot/norm); + tmbb[i][j] = (btot/norm); + } + } + } + } +} + +#ifdef _OPENMP +#pragma omp parallel +#endif +{ +#ifdef __SSE2__ + int j; + __m128 interav, interbv; + +// __m128 piidv = _mm_set1_ps(piid); +#endif +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = 0; i < height; i++ ) { + /* +#ifdef __SSE2__ + for(j = 0; j < width-3; j+=4) { + interav = LVFU(tmaa[i][j]); + interbv = LVFU(tmbb[i][j]); + _mm_storeu_ps(&dst->a[i][j],(interav)); + _mm_storeu_ps(&dst->b[i][j],(interbv)); + } + + // _mm_storeu_ps(&dst->C_p[i][j],_mm_sqrt_ps(SQRV(interbv)+SQRV(interav))); + } + for(; j < width; j++) { + float intera = tmaa[i][j]; + float interb = tmbb[i][j]; + + dst->a[i][j]=(intera); + dst->b[i][j]=(interb); + } +#else +*/ + for(int j = 0; j < width; j++) { + float intera = tmaa[i][j]; + float interb = tmbb[i][j]; + float HH=xatan2f(interb,intera); + float CC=sqrt(SQR(interb/327.68)+SQR(intera/327.68f)); + // if((HH > b_l && HH < t_r) && CC < chrom && skinprot !=0.f){ + if(CC < chrom && skinprot !=0.f){ + + dst->a[i][j]=intera; + dst->b[i][j]=interb; + } + } +//#endif + } +} +} + if(src != dst) { +#ifdef _OPENMP +#pragma omp parallel for +#endif + for(int i = 0; i < height; i++ ) + for(int j = 0; j < width; j++) + dst->L[i][j] = src->L[i][j]; + } + + + for (int i=0; iverbose ) + printf("Lab artifacts:- %d usec\n", t2.etime(t1)); + + +} + + + + } #undef PIX_SORT #undef med3 diff --git a/rtengine/color.cc b/rtengine/color.cc index b8bc213c6..e217930d5 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -28,7 +28,7 @@ using namespace std; namespace rtengine { extern const Settings* settings; - + LUTf Color::cachef; LUTf Color::gamma2curve; @@ -827,6 +827,62 @@ namespace rtengine { + void Color::SkinSatcdbl (float lum, float hue, float chrom, float skinprot, float &scale, bool ciec, bool neg, float b_l, float t_l, float t_r, float b_r, int choice) { + + + + float C9=0.0f, C8=0.0f, C7=0.0f, C4=0.0f, C3=0.0f, C2=0.0f, C1=0.0f; + float H9=0.0f, H8=0.0f, H7=0.0f, H4=0.0f, H3=0.0f, H2=0.0f, H1=0.0f, H10=0.0f,H11=0.0f; + H9=0.05f;H8=0.25f;H7=0.1f;H4=0.02f;H3=0.02f;H2=0.1f;H1=0.1f;H10=-0.2f;H11=-0.2f;//H10 and H11 are curious...H11=-0.8 ?? + C9=8.0f;C8=15.0f;C7=12.0f;C4=7.0f;C3=5.0f;C2=5.0f;C1=5.0f; + + if (ciec) { + float HH; + bool doskin; + if ((float)hue>8.6f && (float)hue<=74.f ) {HH=(1.15f/65.4f)*(float)hue-0.0012f; doskin=true;}//H > 0.15 H<1.3 + else if((float)hue>0.f && (float)hue<=8.6f ) {HH=(0.19f/8.6f )*(float)hue-0.04f; doskin=true;}//H>-0.04 H < 0.15 + else if((float)hue>355.f && (float)hue<=360.f) {HH=(0.11f/5.0f )*(float)hue-7.96f; doskin=true;}//H>-0.15 <-0.04 + else if((float)hue>74.f && (float)hue<95.f ) {HH=(0.30f/21.0f)*(float)hue+0.24285f; doskin=true;}//H>1.3 H<1.6 + else if((float)hue>=95.f && (float)hue<137.5f) {HH= 0.01882*(float)hue-0.18823;}// H>1.6 H<2.4 + else if((float)hue>285.f && (float)hue<=355.f) {HH=0.1642*(float)hue -5.982;}//HH>-1.3 HH <-0.15 + + hue=HH; + + } + // wide area for transition + if((t_r-t_l)<0.55f) t_l=t_r+0.55f;//avoid too small range + + if (lum >= 92.0f && (hue > b_l && hue < t_r) && (chrom > 7.0f && chrom < (18.0f))) scale = (100.f-skinprot*0.4f)/100.1f; + else if (lum >= 85.0f && lum < 92.0f && (hue > b_l+0.05f && hue < t_r) && (chrom > 7.0f && chrom < (35.0f+C9))) scale = (100.f-skinprot*0.4f)/100.1f; + else if ((lum >= 20.f && lum < 85.f) && (hue > (b_l+0.07f + H11) && hue < t_r) && (chrom > 7.0f && chrom < (55.0f+C9) )) scale = (100.f-skinprot*0.4f)/100.1f; + else if (lum < 20.0f && (hue > (b_l+0.07f+H11) && hue < t_r-0.1f) && (chrom > 7.0f && chrom < (45.0f+C1) )) scale = (100.f-skinprot*0.4f)/100.1f; + + // wide area skin color, useful if not accurate colorimetry or if the user has changed hue and saturation + + if (lum >= 92.0f && (hue > t_l+0.4f && hue < t_r) && (chrom > 7.0f && chrom < (15.0f))) scale = (100.f-skinprot*0.6f)/100.1f; + else if (lum >= 85.0f && lum < 92.0f && (hue > t_l+0.4f && hue < t_r-0.3f) && (chrom > 7.0f && chrom < (26.0f+C9))) scale = (100.f-skinprot*0.6f)/100.1f; + else if ((lum >= 20.f && lum < 85.f) && (hue > (b_l+0.07f + H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (48.0f+C9) )) scale = (100.f-skinprot*0.6f)/100.1f; + else if (lum < 20.0f && (hue > (b_l+0.07f+H11) && hue < t_r-0.2f) && (chrom > 7.0f && chrom < (35.0f+C1) )) scale = (100.f-skinprot*0.6f)/100.1f; + + // "real" skin color : take into account a slightly usage of contrast and saturation in RT if option "skin" = 1 + + if (lum >= 85.0f && (hue > (t_l+0.53f-H9) && hue < (t_r+H9)) && (chrom > 8.0f && chrom < (14.0f+C9))) scale = (100.f-skinprot)/100.1f; + else if ((lum >= 70.0f && lum < 85.0f) && (hue > t_l+0.15f && hue < (t_r-0.2f+H8)) && (chrom > 8.0f && chrom < (35.0f+C8))) scale = (100.f-skinprot)/100.1f; + else if ((lum >= 52.0f && lum < 70.0f) && (hue > t_l && hue < (t_r+H7)) && (chrom > 11.0f && chrom < (35.0f+C7))) scale = (100.f-skinprot)/100.1f; + else if ((lum >= 35.0f && lum < 52.0f) && (hue > t_l && hue < (t_r+H4)) && (chrom > 13.0f && chrom < (37.0f+C4))) scale = (100.f-skinprot)/100.1f; + else if ((lum >= 20.0f && lum < 35.0f) && (hue > t_l && hue < (t_r+H3)) && (chrom > 7.0f && chrom <(35.0f+C3) )) scale = (100.f-skinprot)/100.1f; + else if ((lum > 10.0f && lum < 20.0f) && (hue > (t_l-0.25f + H10) && hue < (t_r-0.3f +H2)) && (chrom > 8.0f && chrom < (23.0f+C2))) scale = (100.f-skinprot)/100.1f; + else if ((lum < 10.0f) && (hue > (t_l -0.2f + H10) && hue < (t_r-0.3f+H1)) && (chrom > 8.0f && chrom < (23.0f+C1))) scale = (100.f-skinprot)/100.1f; + + //extended zone for hair, beard and if user adjust high value for skinprot + if(skinprot > 85.f && chrom < 20.f && neg) { + float modula = -0.0666f*skinprot + 6.66f; + scale *= modula; + } + } + + + void Color::scalered ( float rstprotection, float param, float limit, float HH, float deltaHH, float &scale,float &scaleext) { if(rstprotection<99.9999) { diff --git a/rtengine/color.h b/rtengine/color.h index dc579fc40..4d57cb374 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -214,6 +214,8 @@ public: static void transitred (float HH, float Chprov1, float dred, float factorskin, float protect_red, float factorskinext, float deltaHH, float factorsat, float &factor); static void skinred ( double J, double h, double sres, double Sp, float dred, float protect_red, int sk, float rstprotection, float ko, double &s); static void skinredfloat ( float J, float h, float sres, float Sp, float dred, float protect_red, int sk, float rstprotection, float ko, float &s); +// static void scaleredcdbl ( float skinprot, float param, float limit, float HH, float deltaHH, float &scale,float &scaleext); + static void SkinSatcdbl (float lum, float hue, float chrom, float skinprot, float &scale, bool ciec, bool neg, float b_l, float t_l, float t_r, float b_r, int choice); //void gamutmap(LabImage* ); static void gamutmap(float &X, float &Y, float &Z, const double p[3][3]); diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index e3a27c167..8dc9c8a46 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -122,13 +122,10 @@ void Crop::update (int todo) { // re-allocate sub-images and arrays if their dimensions changed bool needsinitupdate = false; - if (!overrideWindow) { + if (!overrideWindow) needsinitupdate = setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); - } - else { + else needsinitupdate = setCropSizes (wx, wy, ww, wh, ws, true); // this set skip=ws - } - // it something has been reallocated, all processing steps have to be performed if (needsinitupdate || (todo & M_HIGHQUAL)) todo = ALL; @@ -151,9 +148,8 @@ void Crop::update (int todo) { if (params.coarse.hflip) tr |= TR_HFLIP; if (params.coarse.vflip) tr |= TR_VFLIP; - if (!needsinitupdate) { + if (!needsinitupdate) setCropSizes (rqcropx, rqcropy, rqcropw, rqcroph, skip, true); - } PreviewProps pp (trafx, trafy, trafw*skip, trafh*skip, skip); parent->imgsrc->getImage (parent->currWB, tr, origCrop, pp, params.toneCurve, params.icm, params.raw ); //ColorTemp::CAT02 (origCrop, ¶ms) ; @@ -258,12 +254,17 @@ void Crop::update (int todo) { if((params.colorappearance.enabled && !settings->autocielab) ||(!params.colorappearance.enabled) ) {parent->ipf.defringe (labnCrop);} parent->ipf.MLsharpen (labnCrop); if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { - parent->ipf.MLmicrocontrast (labnCrop); - parent->ipf.sharpening (labnCrop, (float**)cbuffer); - parent->ipf.dirpyrequalizer (labnCrop); - } + parent->ipf.MLmicrocontrast (labnCrop); + parent->ipf.sharpening (labnCrop, (float**)cbuffer); + } } - + // if (skip==1) { + + if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)) { + parent->ipf.dirpyrequalizer (labnCrop, skip); + // parent->ipf.Lanczoslab (labnCrop,labnCrop , 1.f/skip); + } + // } if(params.colorappearance.enabled){ float fnum = parent->imgsrc->getMetaData()->getFNumber (); // F number float fiso = parent->imgsrc->getMetaData()->getISOSpeed () ; // ISO @@ -286,17 +287,19 @@ void Crop::update (int todo) { if(skip==1) execsharp=true; if (!cieCrop) - cieCrop = new CieImage (cropw, croph); + { cieCrop = new CieImage (cropw, croph); } if(settings->ciecamfloat) { float d; // not used after this block + skip2=skip; parent->ipf.ciecam_02float (cieCrop, float(adap), begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, - dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, 1,(float**)cbuffer, execsharp, d); + dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, 1,(float**)cbuffer, execsharp, d, skip, 1); } else { double dd; // not used after this block + parent->ipf.ciecam_02 (cieCrop,adap, begh, endh, 1, 2, labnCrop, ¶ms, parent->customColCurve1, parent->customColCurve2, parent->customColCurve3, - dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, 1,(float**)cbuffer, execsharp, dd); + dummy, dummy, parent->CAMBrightCurveJ, parent->CAMBrightCurveQ, parent->CAMMean, 5, 1,(float**)cbuffer, execsharp, dd, skip, 1); } } else { diff --git a/rtengine/dcrop.h b/rtengine/dcrop.h index a79815f9f..391832103 100644 --- a/rtengine/dcrop.h +++ b/rtengine/dcrop.h @@ -74,6 +74,7 @@ class Crop : public DetailedCrop, public EditBuffer { public: Crop (ImProcCoordinator* parent, EditDataProvider *editDataProvider); virtual ~Crop (); + int skip2; void mLock () { cropMutex.lock(); } void mUnlock () { cropMutex.lock(); } diff --git a/rtengine/dirpyr_equalizer.cc b/rtengine/dirpyr_equalizer.cc index 0b26723f8..26124045c 100644 --- a/rtengine/dirpyr_equalizer.cc +++ b/rtengine/dirpyr_equalizer.cc @@ -22,6 +22,10 @@ #include #include "curves.h" #include "labimage.h" +#include "color.h" +#include "mytime.h" +//#include "StopWatch.h" + #include "improcfun.h" #include "rawimagesource.h" #include "array2D.h" @@ -46,15 +50,25 @@ namespace rtengine { //sequence of scales static const int scales[8] = {1,2,4,8,16,32,64,128}; + extern const Settings* settings; //sequence of scales - //static const int scales[8] = {1,2,3,6,15,21,28,36}; - //scale is spacing of directional averaging weights - void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, const double * mult, const double dirpyrThreshold ) + void ImProcFunctions :: dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, float ** dest_a, float ** dest_b,const double * mult, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scaleprev) { + // StopWatch Stop1("Dirpyr equalizer"); + + int lastlevel=maxlevel; + if(settings->verbose) printf("Dirpyr scaleprev=%i\n",scaleprev); + float atten123=(float) settings->level123_cbdl; + if(atten123 > 50.f) atten123=50.f; + if(atten123 < 0.f) atten123=0.f; + float atten0=(float) settings->level0_cbdl; + if(atten0 > 40.f) atten123=40.f; + if(atten0 < 0.f) atten0=0.f; + while (fabs(mult[lastlevel-1]-1)<0.001 && lastlevel>0) { lastlevel--; @@ -63,23 +77,37 @@ namespace rtengine { if (lastlevel==0) return; int level; + float multi[5]={1.f,1.f,1.f,1.f,1.f}; + float scalefl[5]; + + for(int lv=0;lv<5;lv++) { + scalefl[lv]= ((float) scales[lv])/(float) scaleprev; + if(lv>=1) {if(scalefl[lv] < 1.f) multi[lv] = (atten123*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];}//modulate action if zoom < 100% + else {if(scalefl[lv] < 1.f) multi[lv] = (atten0*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];}//modulate action if zoom < 100% + + } + if(settings->verbose) printf("CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f\n",multi[0],multi[1],multi[2],multi[3],multi[4]); multi_array2D dirpyrlo (srcwidth, srcheight); level = 0; - int scale = scales[level]; //int thresh = 100 * mult[5]; + int scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + - dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale ); + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale, l_a, l_b, false ); level = 1; while(level < lastlevel) { - scale = scales[level]; - - dirpyr_channel(dirpyrlo[level-1], dirpyrlo[level], srcwidth, srcheight, level, scale ); + + scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + + dirpyr_channel(dirpyrlo[level-1], dirpyrlo[level], srcwidth, srcheight, level, scale, l_a, l_b, false ); level ++; } @@ -89,13 +117,13 @@ namespace rtengine { for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, mult, dirpyrThreshold ); + idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold, l_a, l_b, false, skinprot, gamutlab, b_l,t_l,t_r,b_r, choice ); } scale = scales[0]; - idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, mult, dirpyrThreshold ); + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, l_a, l_b, false, skinprot, gamutlab, b_l,t_l,t_r,b_r, choice ); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -103,6 +131,8 @@ namespace rtengine { for (int i=0; iverbose) printf("CAM dirpyr scaleprev=%i\n",scaleprev); + float atten123=(float) settings->level123_cbdl; + if(atten123 > 50.f) atten123=50.f; + if(atten123 < 0.f) atten123=0.f; +// printf("atten=%f\n",atten); + float atten0=(float) settings->level0_cbdl; + if(atten0 > 40.f) atten123=40.f; + if(atten0 < 0.f) atten0=0.f; + while (fabs(mult[lastlevel-1]-1)<0.001 && lastlevel>0) { lastlevel--; //printf("last level to process %d \n",lastlevel); @@ -126,23 +166,40 @@ namespace rtengine { if (lastlevel==0) return; int level; + + float multi[5]={1.f,1.f,1.f,1.f,1.f}; + float scalefl[5]; + for(int lv=0;lv<5;lv++) { + scalefl[lv]= ((float) scales[lv])/(float) scaleprev; + // if(scalefl[lv] < 1.f) multi[lv] = 1.f; else multi[lv]=(float) mult[lv]; + if (lv>=1) {if(scalefl[lv] < 1.f) multi[lv] = (atten123*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];} + else {if(scalefl[lv] < 1.f) multi[lv] = (atten0*((float) mult[lv] -1.f)/100.f)+1.f; else multi[lv]=(float) mult[lv];} + + + } + if(settings->verbose) printf("CAM CbDL mult0=%f 1=%f 2=%f 3=%f 4=%f\n",multi[0],multi[1],multi[2],multi[3],multi[4]); + + + + multi_array2D dirpyrlo (srcwidth, srcheight); level = 0; - int scale = scales[level]; - //int thresh = 100 * mult[5]; - - dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale ); + int scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + + dirpyr_channel(src, dirpyrlo[0], srcwidth, srcheight, 0, scale, h_p, C_p, true ); level = 1; while(level < lastlevel) { - scale = scales[level]; - - dirpyr_channel(dirpyrlo[level-1], dirpyrlo[level], srcwidth, srcheight, level, scale ); + scale = (int)(scales[level])/scaleprev; + if(scale < 1) scale=1; + + dirpyr_channel(dirpyrlo[level-1], dirpyrlo[level], srcwidth, srcheight, level, scale, h_p, C_p, true ); level ++; } @@ -153,17 +210,17 @@ namespace rtengine { for(int level = lastlevel - 1; level > 0; level--) { - idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, mult, dirpyrThreshold ); + idirpyr_eq_channel(dirpyrlo[level], dirpyrlo[level-1], buffer, srcwidth, srcheight, level, multi, dirpyrThreshold , h_p, C_p, true, skinprot, false, b_l,t_l,t_r,b_r, choice); } scale = scales[0]; - idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, mult, dirpyrThreshold ); + idirpyr_eq_channel(dirpyrlo[0], dst, buffer, srcwidth, srcheight, 0, multi, dirpyrThreshold, h_p, C_p, true, skinprot, false, b_l,t_l,t_r,b_r, choice); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - if(execdir) + if(execdir){ #ifdef _OPENMP #pragma omp parallel for #endif @@ -174,6 +231,7 @@ namespace rtengine { else dst[i][j]=src[i][j]; } + } else for (int i=0; iworkingSpaceInverseMatrix (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]} + }; + bool highlight = params->toneCurve.hrenabled; //Get the value if "highlight reconstruction" is activated + float noisehi = 1.33f*noise*dirpyrThreshold/expf(level*log(3.0)), noiselo = 0.66f*noise*dirpyrThreshold/expf(level*log(3.0)); + //printf("level=%i multlev=%f noisehi=%f noiselo=%f skinprot=%f\n",level,mult[level], noisehi, noiselo, skinprot); + LUTf irangefn (0x20000); for (int i=0; i<0x20000; i++) { if (abs(i-0x10000)>noisehi || mult[level]<1.0) { irangefn[i] = mult[level] ; @@ -402,7 +468,7 @@ void ImProcFunctions::dirpyr_channel(float ** data_fine, float ** data_coarse, i if (abs(i-0x10000)= 0.) { + Color::SkinSatcdbl ((data_fine[i][j])/327.68f, l_a_h[i][j] ,l_b_c[i][j], skinprot, scale, ciec, true, b_l, t_l, t_r, b_r, choice); + buffer[i][j] += (1.f +(irangefn[hipass+0x10000]-1.f)*scale) * hipass ; + } + else { + double skinprotneg = -skinprot; + float correct; + correct=irangefn[hipass+0x10000]; + Color::SkinSatcdbl ((data_fine[i][j])/327.68f, l_a_h[i][j],l_b_c[i][j] , skinprotneg, scale, ciec, false, b_l, t_l, t_r, b_r, choice); + if (scale == 1.f) {//image hard + //buffer[i][j] += hipass ; + buffer[i][j] += (1.f +(correct-1.f)* (1.f- (float) skinprotneg/100.f)) * hipass ; + + } + else {//image soft + buffer[i][j] += (1.f +(correct-1.f)) * hipass ; + } + } + // if(gamutlab) { + // ImProcFunctions::badpixcam (buffer[i][j], 6.0, 10, 2);//for bad pixels + // } + + } + else {//lab + float modhue=atan2(l_b_c[i][j],l_a_h[i][j]); + float modchro=sqrt(SQR((l_b_c[i][j])/327.68f)+SQR((l_a_h[i][j])/327.68f)); + if(skinprot >= 0.) { + Color::SkinSatcdbl ((data_fine[i][j])/327.68f, modhue, modchro, skinprot, scale, ciec, true, b_l, t_l, t_r, b_r, choice); + buffer[i][j] += (1.f +(irangefn[hipass+0x10000]-1.f)*scale) * hipass ; + } + else { + double skinprotneg = -skinprot; + float correct; + Color::SkinSatcdbl ((data_fine[i][j])/327.68f, modhue, modchro, skinprotneg, scale, ciec, false, b_l, t_l, t_r, b_r, choice); + correct=irangefn[hipass+0x10000]; + if (scale == 1.f) {//image hard + buffer[i][j] += (1.f +(correct-1.f)* (1.f- (float)skinprotneg/100.f)) * hipass ; + } + else {//image soft with scale < 1 ==> skin + buffer[i][j] += (1.f +(correct-1.f)) * hipass ; + } + } + /* if(gamutlab) {//disabled + float Lprov1=(buffer[i][j])/327.68f; + float R,G,B; +#ifdef _DEBUG + bool neg=false; + bool more_rgb=false; + //gamut control : Lab values are in gamut + Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f, neg, more_rgb); +#else + //gamut control : Lab values are in gamut + Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f); +#endif + // Color::gamutLchonly(modhue,Lprov1,modchro, R, G, B, wip, highlight, 0.15f, 0.96f);//gamut control in Lab mode ..not in CIECAM + buffer[i][j]=Lprov1*327.68f; + float2 sincosval = xsincosf(modhue); + l_a_h[i][j]=327.68f*modchro*sincosval.y; + l_b_c[i][j]=327.68f*modchro*sincosval.x; + } + */ + } } } } + // float hipass = (data_fine[i][j]-data_coarse[i][j]); + // buffer[i][j] += irangefn[hipass+0x10000] * hipass ; #undef DIRWT_L #undef DIRWT_AB diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc index 313e1ccac..ccb948f48 100644 --- a/rtengine/improccoordinator.cc +++ b/rtengine/improccoordinator.cc @@ -422,13 +422,15 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { delete [] buffer; readyphase++; } + } + // if (scale==1) { if((params.colorappearance.enabled && !settings->autocielab) || (!params.colorappearance.enabled)){ - //if(params.colorappearance.enabled && !params.colorappearance.sharpcie){ progress ("Pyramid equalizer...",100*readyphase/numofphases); - ipf.dirpyrequalizer (nprevl); + ipf.dirpyrequalizer (nprevl, scale); + //ipf.Lanczoslab (nprevl, nprevl, 1.f/scale); readyphase++; } - } + // } //L histo and Chroma histo for ciecam // histogram well be for Lab (Lch) values, because very difficult to do with J,Q, M, s, C @@ -491,12 +493,12 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) { if (!CAMBrightCurveQ && (params.colorappearance.algo=="QM" || params.colorappearance.algo=="ALL")) CAMBrightCurveQ(65536,0); if(settings->ciecamfloat){ - ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, d); + ipf.ciecam_02float (ncie, float(adap), begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, d, scale, 1); if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*(double)d); if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap);//real value of adapt scene luminosity } else { - ipf.ciecam_02 (ncie, adap, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, dd); + ipf.ciecam_02 (ncie, adap, begh, endh, pW, 2, nprevl, ¶ms, customColCurve1,customColCurve2,customColCurve3, histLCAM, histCCAM, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, execsharp, dd, scale, 1); if(params.colorappearance.autodegree && acListener && params.colorappearance.enabled) acListener->autoCamChanged(100.*dd); if(params.colorappearance.autoadapscen && acListener && params.colorappearance.enabled) acListener->adapCamChanged(adap); } diff --git a/rtengine/improcfun.cc b/rtengine/improcfun.cc index 5d5d667e0..5a5f6d572 100644 --- a/rtengine/improcfun.cc +++ b/rtengine/improcfun.cc @@ -249,9 +249,11 @@ void ImProcFunctions::firstAnalysis (Imagefloat* original, const ProcParams* par // Copyright (c) 2012 Jacques Desmis void ImProcFunctions::ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params , const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, - LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, double &d) + LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, double &d, int scalecd, int rtt) { if(params->colorappearance.enabled) { +//int lastskip; +//if(rtt==1) {lastskip=scalecd;} //not for Rtthumbnail #ifdef _DEBUG MyTime t1e,t2e; @@ -463,7 +465,7 @@ if(params->colorappearance.enabled) { #ifndef _DEBUG -#pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh,nc2,f2,c2, alg,algepd, gamu, highlight, rstprotection, pW) +#pragma omp parallel default(shared) firstprivate(lab,xw1,xw2,yw1,yw2,zw1,zw2,pilot,jli,chr,yb,la,yb2,la2,fl,nc,f,c, height,width,begh, endh,nc2,f2,c2, alg,algepd, gamu, highlight, rstprotection, pW, scalecd) #endif { //matrix for current working space TMatrix wiprof = iccStore->workingSpaceInverseMatrix (params->icm.working); @@ -944,17 +946,44 @@ if(settings->autocielab) { //all this treatments reduce artifacts, but can lead to slightly different results if(params->defringe.enabled) if(execsharp) ImProcFunctions::defringecam (ncie);// -if(params->colorappearance.badpixsl > 0) if(execsharp){ int mode=params->colorappearance.badpixsl; - ImProcFunctions::badpixcam (ncie, 3.4, 5, mode);//for bad pixels - } +//if(params->dirpyrequalizer.enabled) if(execsharp) { +if(params->dirpyrequalizer.enabled) { + if(params->dirpyrequalizer.gamutlab /*&& execsharp*/) { + float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; + float t_l = static_cast(params->dirpyrequalizer.hueskin.value[1]) / 100.0f; + float b_r = static_cast(params->dirpyrequalizer.hueskin.value[2]) / 100.0f; + float t_r = static_cast(params->dirpyrequalizer.hueskin.value[3]) / 100.0f; + int choice=0; + bool alread=false; + float artifact=(float) settings->artifact_cbdl; + if(artifact>6.f) artifact=6.f; + if(artifact <0.f) artifact=1.f; + int hotbad=0; + float chrom=50.f; + {ImProcFunctions::badpixcam (ncie, artifact, 5, 2 , b_l, t_l, t_r, b_r,params->dirpyrequalizer.skinprotect , chrom, hotbad); alread=true; }//enabled remove artifacts for cbDL +} +} +if(params->colorappearance.badpixsl > 0) if(execsharp) { + int mode=params->colorappearance.badpixsl; + ImProcFunctions::badpixcam (ncie, 3.4, 5, mode, 0, 0, 0, 0, 0, 0, 1);//for bad pixels CIECAM +} if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastcam(ncie); if(params->sharpening.enabled) if(execsharp) {ImProcFunctions::sharpeningcam (ncie, (float**)buffer);} //sharpening adapted to CIECAM -if(params->dirpyrequalizer.enabled) if(execsharp) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, true);//contrast by detail adapted to CIECAM - +//if(params->dirpyrequalizer.enabled) if(execsharp) { +if(params->dirpyrequalizer.enabled /*&& (execsharp)*/) { + float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; + float t_l = static_cast(params->dirpyrequalizer.hueskin.value[1]) / 100.0f; + float b_r = static_cast(params->dirpyrequalizer.hueskin.value[2]) / 100.0f; + float t_r = static_cast(params->dirpyrequalizer.hueskin.value[3]) / 100.0f; + int choice=0;//not disabled in case of ! always 0 +// if (params->dirpyrequalizer.algo=="FI") choice=0; +// else if(params->dirpyrequalizer.algo=="LA") choice=1; + if(rtt==1) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l,t_l,t_r,b_r, choice, scalecd);//contrast by detail adapted to CIECAM +} float Qredi= ( 4.0 / c_) * ( a_w + 4.0 ); float co_e=(pow(f_l,0.25f)); @@ -1114,10 +1143,13 @@ if((params->colorappearance.tonecie || (params->colorappearance.tonecie && param // Copyright (c) 2012 Jacques Desmis void ImProcFunctions::ciecam_02float (CieImage* ncie, float adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve2,const ColorAppearance & customColCurve3, - LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, float &d) + LUTu & histLCAM, LUTu & histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, float &d, int scalecd, int rtt) { if(params->colorappearance.enabled) { -//printf("ciecam float\n"); +//int lastskip; +//if(rtt==1) {lastskip=scalecd;} //not for Rtthumbnail + + #ifdef _DEBUG MyTime t1e,t2e; t1e.set(); @@ -1795,10 +1827,30 @@ if(settings->autocielab) { //all this treatments reduce artefacts, but can leed to slighty different results if(params->defringe.enabled) if(execsharp) ImProcFunctions::defringecam (ncie);//defringe adapted to CIECAM +//if(params->dirpyrequalizer.enabled) if(execsharp) { +if(params->dirpyrequalizer.enabled) { + if(params->dirpyrequalizer.gamutlab /*&& execsharp*/) {//remove artifacts by gaussian blur - skin control + float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; + float t_l = static_cast(params->dirpyrequalizer.hueskin.value[1]) / 100.0f; + float b_r = static_cast(params->dirpyrequalizer.hueskin.value[2]) / 100.0f; + float t_r = static_cast(params->dirpyrequalizer.hueskin.value[3]) / 100.0f; + int choice=0; + bool alread=false; + float artifact=(float) settings->artifact_cbdl; + if(artifact > 6.f) artifact=6.f; + if(artifact <0.f) artifact=1.f; + + int hotbad=0; + float chrom=50.f; + ImProcFunctions::badpixcam (ncie, artifact, 5, 2 , b_l, t_l, t_r, b_r, params->dirpyrequalizer.skinprotect, chrom, hotbad); alread=true;//enabled remove artifacts for cbDL +} +} -if(params->colorappearance.badpixsl > 0) if(execsharp){ int mode=params->colorappearance.badpixsl; - ImProcFunctions::badpixcam (ncie, 3.0, 10, mode);//for bad pixels - } +//if(params->colorappearance.badpixsl > 0) { int mode=params->colorappearance.badpixsl; +if(params->colorappearance.badpixsl > 0) if(execsharp){ + int mode=params->colorappearance.badpixsl; + ImProcFunctions::badpixcam (ncie, 3.0, 10, mode, 0, 0, 0, 0, 0, 0, 1);//for bad pixels CIECAM +} if(params->impulseDenoise.enabled) if(execsharp) ImProcFunctions::impulsedenoisecam (ncie);//impulse adapted to CIECAM @@ -1806,8 +1858,24 @@ if (params->sharpenMicro.enabled)if(execsharp) ImProcFunctions::MLmicrocontrastc if(params->sharpening.enabled) if(execsharp) {ImProcFunctions::sharpeningcam (ncie, (float**)buffer);} //sharpening adapted to CIECAM -if(params->dirpyrequalizer.enabled) if(execsharp) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, true);//contrast by detail adapted to CIECAM +//if(params->dirpyrequalizer.enabled) if(execsharp) { +if(params->dirpyrequalizer.enabled /*&& execsharp*/) { + float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; + float t_l = static_cast(params->dirpyrequalizer.hueskin.value[1]) / 100.0f; + float b_r = static_cast(params->dirpyrequalizer.hueskin.value[2]) / 100.0f; + float t_r = static_cast(params->dirpyrequalizer.hueskin.value[3]) / 100.0f; + int choice=0;// I have not suppress this statement in case of !! always to 0 +// if(params->dirpyrequalizer.algo=="FI") choice=0; +// else if(params->dirpyrequalizer.algo=="LA") choice=1; + if(rtt==1) dirpyr_equalizercam(ncie, ncie->sh_p, ncie->sh_p, ncie->W, ncie->H, ncie->h_p, ncie->C_p, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, true, params->dirpyrequalizer.gamutlab, b_l,t_l,t_r,b_r, choice, scalecd);//contrast by detail adapted to CIECAM +/* +if(params->colorappearance.badpixsl > 0) if(execsharp){ int mode=params->colorappearance.badpixsl; +printf("BADPIX"); + ImProcFunctions::badpixcam (ncie, 8.0, 10, mode);//for bad pixels + } + */ +} float Qredi= ( 4.0f / c_) * ( a_w + 4.0f ); float co_e=(pow_F(f_l,0.25f)); @@ -3657,6 +3725,10 @@ void ImProcFunctions::chromiLuminanceCurve (EditBuffer *editBuffer, int pW, LabI if (chCurve) delete chCurve; if (lhCurve) delete lhCurve; if (hhCurve) delete hhCurve; + + // t2e.set(); + // printf("Chromil took %d µsec\n",t2e.etime(t1e)); + } @@ -3767,16 +3839,34 @@ void ImProcFunctions::colorCurve (LabImage* lold, LabImage* lnew) { } - void ImProcFunctions::badpixcam(CieImage* ncie, double rad, int thr, int mode){ - if(ncie->W>=8 && ncie->H>=8) Badpixelscam(ncie, ncie, rad, thr, mode); + void ImProcFunctions::badpixcam(CieImage* ncie, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad){ + if(ncie->W>=8 && ncie->H>=8) Badpixelscam(ncie, ncie, rad, thr, mode, b_l, t_l, t_r,b_r, skinprot, chrom, hotbad); } - void ImProcFunctions::dirpyrequalizer (LabImage* lab) { + void ImProcFunctions::badpixlab(LabImage* lab, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom){ + if(lab->W>=8 && lab->H>=8) BadpixelsLab(lab, lab, rad, thr, mode, b_l, t_l, t_r,b_r, skinprot, chrom); + } + + void ImProcFunctions::dirpyrequalizer (LabImage* lab, int scale) { if (params->dirpyrequalizer.enabled && lab->W>=8 && lab->H>=8) { + float b_l = static_cast(params->dirpyrequalizer.hueskin.value[0]) / 100.0f; + float t_l = static_cast(params->dirpyrequalizer.hueskin.value[1]) / 100.0f; + float b_r = static_cast(params->dirpyrequalizer.hueskin.value[2]) / 100.0f; + float t_r = static_cast(params->dirpyrequalizer.hueskin.value[3]) / 100.0f; + int choice=0;//I have not disabled this statement in case of ! always 0 + // if (params->dirpyrequalizer.algo=="FI") choice=0; + // else if(params->dirpyrequalizer.algo=="LA") choice=1; + float artifact=(float) settings->artifact_cbdl; + if(artifact > 6.f) artifact =6.f; + if(artifact <0.f) artifact=1.f; + + float chrom = 50.f; + if(params->dirpyrequalizer.gamutlab) + ImProcFunctions::badpixlab (lab, artifact, 5, 3, b_l, t_l, t_r, b_r, params->dirpyrequalizer.skinprotect, chrom);//for artifacts //dirpyrLab_equalizer(lab, lab, params->dirpyrequalizer.mult); - dirpyr_equalizer(lab->L, lab->L, lab->W, lab->H, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold); + dirpyr_equalizer(lab->L, lab->L, lab->W, lab->H, lab->a, lab->b, lab->a, lab->b, params->dirpyrequalizer.mult, params->dirpyrequalizer.threshold, params->dirpyrequalizer.skinprotect, params->dirpyrequalizer.gamutlab, b_l,t_l,t_r,b_r, choice, scale); } } void ImProcFunctions::EPDToneMapCIE(CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates, int skip){ diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 8196defde..73596c590 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -174,7 +174,6 @@ class ImProcFunctions { bool iGamma; // true if inverse gamma has to be applied in rgbProc double g; - static LUTf cachef; float noisered; float noiseblue; @@ -205,10 +204,10 @@ class ImProcFunctions { void luminanceCurve (LabImage* lold, LabImage* lnew, LUTf &curve); void ciecam_02float (CieImage* ncie, float adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, - LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, float &d); + LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, float &d, int scalecd, int rtt); void ciecam_02 (CieImage* ncie, double adap, int begh, int endh, int pW, int pwb, LabImage* lab, const ProcParams* params, const ColorAppearance & customColCurve1, const ColorAppearance & customColCurve, const ColorAppearance & customColCurve3, - LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, double &d); + LUTu &histLCAM, LUTu &histCCAM, LUTf & CAMBrightCurveJ, LUTf & CAMBrightCurveQ, float &mean, int Iterates, int scale, float** buffer, bool execsharp, double &d, int scalecd, int rtt); void chromiLuminanceCurve (EditBuffer *editBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve,LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLCurve, LUTu &histLurve); void vibrance (LabImage* lab);//Jacques' vibrance void colorCurve (LabImage* lold, LabImage* lnew); @@ -218,6 +217,8 @@ class ImProcFunctions { double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage); void lab2monitorRgb (LabImage* lab, Image8* image); void resize (Image16* src, Image16* dst, float dScale); + // void Lanczoslab (LabImage* src, LabImage* dst, float scale); + void deconvsharpening (LabImage* lab, float** buffer); void deconvsharpeningcam (CieImage* ncie, float** buffer); void MLsharpen (LabImage* lab);// Manuel's clarity / sharpening @@ -230,7 +231,7 @@ class ImProcFunctions { void impulse_nrcam (CieImage* ncie, double thresh); void dirpyrdenoise (LabImage* src);//Emil's pyramid denoise - void dirpyrequalizer (LabImage* lab);//Emil's equalizer + void dirpyrequalizer (LabImage* lab, int scale);//Emil's equalizer void EPDToneMap(LabImage *lab, unsigned int Iterates = 0, int skip = 1); void EPDToneMapCIE(CieImage *ncie, float a_w, float c_, float w_h, int Wid, int Hei, int begh, int endh, float minQ, float maxQ, unsigned int Iterates=0, int skip =1); @@ -272,18 +273,20 @@ class ImProcFunctions { float MadMax(float * HH_Coeffs, int &max, int datalen); // pyramid equalizer - void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, const double * mult, const double dirpyrThreshold);//Emil's directional pyramid equalizer - void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, const double * mult, const double dirpyrThreshold, bool execdir );//Emil's directional pyramid equalizer - void dirpyr_channel (float ** data_fine, float ** data_coarse, int width, int height, int level, int scale ); - void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, const double * mult, const double dirpyrThreshold ); + void dirpyr_equalizer (float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, float ** dest_a, float ** dest_b, const double * mult, const double dirpyrThreshold, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid equalizer + void dirpyr_equalizercam (CieImage* ncie, float ** src, float ** dst, int srcwidth, int srcheight, float ** h_p, float ** C_p, const double * mult, const double dirpyrThreshold, const double skinprot, bool execdir, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice, int scale);//Emil's directional pyramid equalizer + void dirpyr_channel (float ** data_fine, float ** data_coarse, int width, int height, int level, int scale, float ** l_a_h, float ** l_b_c, bool ciec); + void idirpyr_eq_channel (float ** data_coarse, float ** data_fine, float ** buffer, int width, int height, int level, float multi[5], const double dirpyrThreshold, float ** l_a_h, float ** l_b_c, bool ciec, const double skinprot, const bool gamutlab, float b_l, float t_l, float t_r, float b_r, int choice); void defringe (LabImage* lab); void defringecam (CieImage* ncie); - void badpixcam (CieImage* ncie, double rad, int thr, int mode); + void badpixcam (CieImage* ncie, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); + void badpixlab (LabImage* lab, double rad, int thr, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); void PF_correct_RT (LabImage * src, LabImage * dst, double radius, int thresh); void PF_correct_RTcam (CieImage * src, CieImage * dst, double radius, int thresh); - void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode); + void Badpixelscam(CieImage * src, CieImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom, int hotbad); + void BadpixelsLab(LabImage * src, LabImage * dst, double radius, int thresh, int mode, float b_l, float t_l, float t_r, float b_r, float skinprot, float chrom); Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, bool standard_gamma); Image16* lab2rgb16b (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile, Glib::ustring profi, Glib::ustring gam, bool freegamma, double gampos, double slpos, double &ga0, double &ga1, double &ga2, double &ga3, double &ga4, double &ga5, double &ga6);// for gamma output diff --git a/rtengine/ipresize.cc b/rtengine/ipresize.cc index 382be169a..c5ee0bcb5 100644 --- a/rtengine/ipresize.cc +++ b/rtengine/ipresize.cc @@ -19,11 +19,11 @@ #include "improcfun.h" #include "rt_math.h" - #ifdef _OPENMP #include #endif - +#include "sleef.c" +#include "opthelper.h" //#define PROFILE #ifdef PROFILE @@ -40,7 +40,7 @@ static inline float Lanc(float x, float a) return 0.0f; else { x = static_cast(M_PI) * x; - return sinf(x) * sinf(x / a) / (x * x / a); + return a * xsinf(x) * xsinf(x / a) / (x * x); } } @@ -50,7 +50,9 @@ static void Lanczos(const Image16* src, Image16* dst, float scale) const float a = 3.0f; const float sc = min(scale, 1.0f); const int support = static_cast(2.0f * a / sc) + 1; - + +#pragma omp parallel +{ // storage for precomputed parameters for horisontal interpolation float * wwh = new float[support * dst->width]; int * jj0 = new int[dst->width]; @@ -90,9 +92,8 @@ static void Lanczos(const Image16* src, Image16* dst, float scale) w[k] /= ws; } } - // Phase 2: do actual interpolation - +#pragma omp for for (int i = 0; i < dst->height; i++) { // y coord of the center of pixel on src image @@ -106,7 +107,7 @@ static void Lanczos(const Image16* src, Image16* dst, float scale) int ii0 = max(0, static_cast(floorf(y0 - a / sc)) + 1); int ii1 = min(src->height, static_cast(floorf(y0 + a / sc)) + 1); - + // calculate weights for vertical interpolation for (int ii = ii0; ii < ii1; ii++) { int k = ii - ii0; @@ -137,7 +138,7 @@ static void Lanczos(const Image16* src, Image16* dst, float scale) lg[j] = g; lb[j] = b; } - + // Do horizontal interpolation for(int j = 0; j < dst->width; j++) { @@ -166,9 +167,174 @@ static void Lanczos(const Image16* src, Image16* dst, float scale) delete[] lg; delete[] lb; } +} + +// this function is implemented for future use and not tested yet +SSEFUNCTION static void Lanczos(const LabImage* src, LabImage* dst, float scale) +{ + const float delta = 1.0f / scale; + const float a = 3.0f; + const float sc = min(scale, 1.0f); + const int support = static_cast(2.0f * a / sc) + 1; + +#pragma omp parallel +{ + // storage for precomputed parameters for horisontal interpolation + float * wwh = new float[support * dst->W]; + int * jj0 = new int[dst->W]; + int * jj1 = new int[dst->W]; + + // temporal storage for vertically-interpolated row of pixels + float * lL = new float[src->W]; + float * la = new float[src->W]; + float * lb = new float[src->W]; + + // Phase 1: precompute coefficients for horisontal interpolation + + for (int j = 0; j < dst->W; j++) { + + // x coord of the center of pixel on src image + float x0 = (static_cast(j) + 0.5f) * delta - 0.5f; + + // weights for interpolation in horisontal direction + float * w = wwh + j * support; + + // sum of weights used for normalization + float ws = 0.0f; + + jj0[j] = max(0, static_cast(floorf(x0 - a / sc)) + 1); + jj1[j] = min(src->W, static_cast(floorf(x0 + a / sc)) + 1); + + // calculate weights + for (int jj = jj0[j]; jj < jj1[j]; jj++) { + int k = jj - jj0[j]; + float z = sc * (x0 - static_cast(jj)); + w[k] = Lanc(z, a); + ws += w[k]; + } + + // normalize weights + for (int k = 0; k < support; k++) { + w[k] /= ws; + } + } + // Phase 2: do actual interpolation +#pragma omp for + for (int i = 0; i < dst->H; i++) { + + // y coord of the center of pixel on src image + float y0 = (static_cast(i) + 0.5f) * delta - 0.5f; + + // weights for interpolation in y direction + float w[support]; + + // sum of weights used for normalization + float ws= 0.0f; + + int ii0 = max(0, static_cast(floorf(y0 - a / sc)) + 1); + int ii1 = min(src->H, static_cast(floorf(y0 + a / sc)) + 1); + + // calculate weights for vertical interpolation + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + float z = sc * (y0 - static_cast(ii)); + w[k] = Lanc(z, a); + ws += w[k]; + } + + // normalize weights + for (int k = 0; k < support; k++) { + w[k] /= ws; + } + + // Do vertical interpolation. Store results. +#ifdef __SSE299__ // actually disabled. To enable replace __SSE299__ by __SSE2__ + __m128 Lv,av,bv,wkv; + int j; + for (j = 0; j < src->W-3; j+=4) { + Lv = _mm_setzero_ps(); + av = _mm_setzero_ps(); + bv = _mm_setzero_ps(); + + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + wkv = LVFU(w[k]); + Lv += wkv * LVFU(src->L[ii][j]); + av += wkv * LVFU(src->a[ii][j]); + bv += wkv * LVFU(src->b[ii][j]); + } + + _mm_storeu_ps(&lL[j],Lv); + _mm_storeu_ps(&la[j],av); + _mm_storeu_ps(&lb[j],bv); + } + for (; j < src->W; j++) { + + float L = 0.0f, a = 0.0f, b = 0.0f; + + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + + L += w[k] * src->L[ii][j]; + a += w[k] * src->a[ii][j]; + b += w[k] * src->b[ii][j]; + } + + lL[j] = L; + la[j] = a; + lb[j] = b; + } + +#else + for (int j = 0; j < src->W; j++) { + + float L = 0.0f, a = 0.0f, b = 0.0f; + + for (int ii = ii0; ii < ii1; ii++) { + int k = ii - ii0; + + L += w[k] * src->L[ii][j]; + a += w[k] * src->a[ii][j]; + b += w[k] * src->b[ii][j]; + } + + lL[j] = L; + la[j] = a; + lb[j] = b; + } +#endif + // Do horizontal interpolation + for(int j = 0; j < dst->W; j++) { + + float * wh = wwh + support * j; + + float L = 0.0f, a = 0.0f, b = 0.0f; + + for (int jj = jj0[j]; jj < jj1[j]; jj++) { + int k = jj - jj0[j]; + + L += wh[k] * lL[jj]; + a += wh[k] * la[jj]; + b += wh[k] * lb[jj]; + } + + dst->L[i][j] = L; + dst->a[i][j] = a; + dst->b[i][j] = b; + } + } + + delete[] wwh; + delete[] jj0; + delete[] jj1; + delete[] lL; + delete[] la; + delete[] lb; +} +} + void ImProcFunctions::resize (Image16* src, Image16* dst, float dScale) { - #ifdef PROFILE time_t t1 = clock(); #endif diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 8d58b891c..0c2050576 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -272,9 +272,14 @@ enum ProcEvent { EvLLHCurve=246, EvLHHCurve=247, EvDirPyrEqualizerThreshold=248, - EvDPDNenhance=249, - EvBWMethodalg=250, - NUMOFEVENTS=251 + EvDPDNenhance=249, + EvBWMethodalg=250, + EvDirPyrEqualizerSkin=251, + EvDirPyrEqlgamutlab=252, + EvDirPyrEqualizerHueskin=253, +// EvDirPyrEqualizeralg=254, + + NUMOFEVENTS=254 }; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 57bee1ceb..fff9b3985 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -430,11 +430,16 @@ void ProcParams::setDefaults () { icm.freegamma = false; dirpyrequalizer.enabled = false; + dirpyrequalizer.gamutlab = false; for(int i = 0; i < 5; i ++) { dirpyrequalizer.mult[i] = 1.0; } dirpyrequalizer.threshold = 0.2; + dirpyrequalizer.skinprotect = 0.; + dirpyrequalizer.hueskin.setValues(-5, 25, 170, 120); //default (b_l 0, t_l 30, b_r 170, t_r 120); + // dirpyrequalizer.algo = "FI"; + hsvequalizer.hcurve.clear (); hsvequalizer.hcurve.push_back (FCT_Linear); hsvequalizer.scurve.clear (); @@ -1005,6 +1010,7 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol // save directional pyramid equalizer parameters if (!pedited || pedited->dirpyrequalizer.enabled) keyFile.set_boolean ("Directional Pyramid Equalizer", "Enabled", dirpyrequalizer.enabled); + if (!pedited || pedited->dirpyrequalizer.gamutlab) keyFile.set_boolean ("Directional Pyramid Equalizer", "Gamutlab", dirpyrequalizer.gamutlab); for(int i = 0; i < 5; i++) { std::stringstream ss; @@ -1012,6 +1018,12 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->dirpyrequalizer.mult[i]) keyFile.set_double("Directional Pyramid Equalizer", ss.str(), dirpyrequalizer.mult[i]); } if (!pedited || pedited->dirpyrequalizer.threshold) keyFile.set_double ("Directional Pyramid Equalizer", "Threshold", dirpyrequalizer.threshold); + if (!pedited || pedited->dirpyrequalizer.skinprotect) keyFile.set_double ("Directional Pyramid Equalizer", "Skinprotect", dirpyrequalizer.skinprotect); + // if (!pedited || pedited->dirpyrequalizer.algo) keyFile.set_string ("Directional Pyramid Equalizer", "Algorithm", dirpyrequalizer.algo); + if (!pedited || pedited->dirpyrequalizer.hueskin) { + Glib::ArrayHandle thresh (dirpyrequalizer.hueskin.value, 4, Glib::OWNERSHIP_NONE); + keyFile.set_integer_list("Directional Pyramid Equalizer", "Hueskin", thresh); + } // save hsv equalizer parameters if (!pedited || pedited->hsvequalizer.hcurve) { @@ -1620,7 +1632,7 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "InputProfile")) { icm.input = expandRelativePath(fname, "file:", keyFile.get_string ("Color Management", "InputProfile")); if (pedited) pedited->icm.input = true; } if (keyFile.has_key ("Color Management", "ToneCurve")) { icm.toneCurve = keyFile.get_boolean ("Color Management", "ToneCurve"); if (pedited) pedited->icm.toneCurve = true; } if (keyFile.has_key ("Color Management", "BlendCMSMatrix")) { icm.blendCMSMatrix = keyFile.get_boolean ("Color Management", "BlendCMSMatrix"); if (pedited) pedited->icm.blendCMSMatrix = true; } - if (keyFile.has_key ("Color Management", "DCPIlluminant")) { icm.dcpIlluminant = keyFile.get_integer ("Color Management", "DCPIlluminant"); if (pedited) pedited->icm.dcpIlluminant = true; } + if (keyFile.has_key ("Color Management", "DCPIlluminant")) { icm.dcpIlluminant = keyFile.get_integer ("Color Management", "DCPIlluminant"); if (pedited) pedited->icm.dcpIlluminant = true; } if (keyFile.has_key ("Color Management", "WorkingProfile")) { icm.working = keyFile.get_string ("Color Management", "WorkingProfile"); if (pedited) pedited->icm.working = true; } if (keyFile.has_key ("Color Management", "OutputProfile")) { icm.output = keyFile.get_string ("Color Management", "OutputProfile"); if (pedited) pedited->icm.output = true; } if (keyFile.has_key ("Color Management", "Gammafree")) { icm.gamma = keyFile.get_string ("Color Management", "Gammafree"); if (pedited) pedited->icm.gamfree = true; } @@ -1632,7 +1644,15 @@ if (keyFile.has_group ("Color Management")) { // load directional pyramid equalizer parameters if (keyFile.has_group ("Directional Pyramid Equalizer")) { - if (keyFile.has_key ("Directional Pyramid Equalizer", "Enabled")) { dirpyrequalizer.enabled = keyFile.get_boolean ("Directional Pyramid Equalizer", "Enabled"); if (pedited) pedited->dirpyrequalizer.enabled = true; } + if (keyFile.has_key ("Directional Pyramid Equalizer", "Enabled")) { dirpyrequalizer.enabled = keyFile.get_boolean ("Directional Pyramid Equalizer", "Enabled"); if (pedited) pedited->dirpyrequalizer.enabled = true; } + if (keyFile.has_key ("Directional Pyramid Equalizer", "Gamutlab")) { dirpyrequalizer.gamutlab = keyFile.get_boolean ("Directional Pyramid Equalizer", "Gamutlab"); if (pedited) pedited->dirpyrequalizer.gamutlab = true; } + // if (keyFile.has_key ("Directional Pyramid Equalizer", "Algorithm")) { dirpyrequalizer.algo = keyFile.get_string ("Directional Pyramid Equalizer", "Algorithm"); if (pedited) pedited->dirpyrequalizer.algo = true; } + if (keyFile.has_key ("Directional Pyramid Equalizer", "Hueskin")) { + Glib::ArrayHandle thresh = keyFile.get_integer_list ("Directional Pyramid Equalizer", "Hueskin"); + dirpyrequalizer.hueskin.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 300), min(thresh.data()[3], 300)); + if (pedited) pedited->dirpyrequalizer.hueskin = true; + } + if (ppVersion < 316) { for(int i = 0; i < 5; i ++) { std::stringstream ss; @@ -1651,7 +1671,8 @@ if (keyFile.has_group ("Directional Pyramid Equalizer")) { ss << "Mult" << i; if(keyFile.has_key ("Directional Pyramid Equalizer", ss.str())) { dirpyrequalizer.mult[i] = keyFile.get_double ("Directional Pyramid Equalizer", ss.str()); if (pedited) pedited->dirpyrequalizer.mult[i] = true; } } - if(keyFile.has_key ("Directional Pyramid Equalizer", "Threshold")) { dirpyrequalizer.threshold = keyFile.get_double ("Directional Pyramid Equalizer", "Threshold"); if (pedited) pedited->dirpyrequalizer.threshold = true; } + if(keyFile.has_key ("Directional Pyramid Equalizer", "Threshold")) { dirpyrequalizer.threshold = keyFile.get_double ("Directional Pyramid Equalizer", "Threshold"); if (pedited) pedited->dirpyrequalizer.threshold = true; } + if(keyFile.has_key ("Directional Pyramid Equalizer", "Skinprotect")) { dirpyrequalizer.skinprotect = keyFile.get_double ("Directional Pyramid Equalizer", "Skinprotect"); if (pedited) pedited->dirpyrequalizer.skinprotect = true; } } } @@ -2017,6 +2038,10 @@ bool ProcParams::operator== (const ProcParams& other) { && icm.gampos == other.icm.gampos && icm.slpos == other.icm.slpos && dirpyrequalizer == other.dirpyrequalizer + // && dirpyrequalizer.algo == other.dirpyrequalizer.algo + && dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin + && dirpyrequalizer.threshold == other.dirpyrequalizer.threshold + && dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect && hsvequalizer.hcurve == other.hsvequalizer.hcurve && hsvequalizer.scurve == other.hsvequalizer.scurve && hsvequalizer.vcurve == other.hsvequalizer.vcurve diff --git a/rtengine/procparams.h b/rtengine/procparams.h index f3604b459..1fa0d60b5 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -745,10 +745,16 @@ class DirPyrEqualizerParams { public: bool enabled; + bool gamutlab; double mult[5]; double threshold; + double skinprotect; + Threshold hueskin; + // Glib::ustring algo; + + DirPyrEqualizerParams() : hueskin(20, 80, 2000, 1200, false) {}; }; - + /** * HSV equalizer params */ diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 1c4d31f3e..90e37ceab 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -269,8 +269,12 @@ LUMINANCECURVE, // EvLCLCurve LUMINANCECURVE, // EvLLHCurve LUMINANCECURVE, // EvLHHCurve DIRPYREQUALIZER, // EvDirPyrEqualizerThreshold -ALLNORAW, // EvDPDNenhance -RGBCURVE //EvBWMethodalg +ALLNORAW, // EvDPDNenhance +RGBCURVE, // EvBWMethodalg +DIRPYREQUALIZER, // EvDirPyrEqualizerSkin +DIRPYREQUALIZER, // EvDirPyrEqlgamutlab +DIRPYREQUALIZER // EvDirPyrEqualizerHueskin +//DIRPYREQUALIZER // EvDirPyrEqualizeralg //LUMINANCECURVE // EvCATsharpcie diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc index 5f8da119c..6d8e3603f 100644 --- a/rtengine/rtthumbnail.cc +++ b/rtengine/rtthumbnail.cc @@ -38,6 +38,8 @@ #include "rawimage.h" #include "jpeg.h" #include "../rtgui/ppversion.h" +#include "improccoordinator.h" + extern Options options; @@ -556,7 +558,6 @@ IImage8* Thumbnail::quickProcessImage (const procparams::ProcParams& params, int // Full thumbnail processing, second stage if complete profile exists IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rheight, TypeInterpolation interp, std::string camName, double focalLen, double focalLen35mm, float focusDist, float shutter, float fnumber, float iso,std::string expcomp_, double& myscale) { - // check if the WB's equalizer value has changed if (wbEqual < (params.wb.equal-5e-4) || wbEqual > (params.wb.equal+5e-4)) { wbEqual = params.wb.equal; @@ -564,7 +565,6 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei ColorTemp cTemp; cTemp.mul2temp (redAWBMul, greenAWBMul, blueAWBMul, wbEqual, autoWBTemp, autoWBGreen); } - // compute WB multipliers ColorTemp currWB = ColorTemp (params.wb.temperature, params.wb.green, params.wb.equal,params.wb.method); if (params.wb.method=="Camera") { @@ -847,7 +847,11 @@ IImage8* Thumbnail::processImage (const procparams::ProcParams& params, int rhei LUTf CAMBrightCurveJ; LUTf CAMBrightCurveQ; float CAMMean; - ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 6, (float**)buffer, execsharp, d); + int sk; + int scale; + sk=16; + int rtt=0; + ipf.ciecam_02float (cieView, adap, begh, endh, 1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 6, (float**)buffer, execsharp, d, sk, rtt); for (int i=0; iheight / fh; myscale = 1.0 / myscale; - /* // apply crop if (params.crop.enabled) { int ix = 0; diff --git a/rtengine/settings.h b/rtengine/settings.h index d725469e5..57fa9e785 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -54,9 +54,12 @@ namespace rtengine { int protectred; double protectredh; bool ciebadpixgauss; - int CRI_color; // N° for display Lab value ; 0 disabled + int CRI_color; // N� for display Lab value ; 0 disabled // bool bw_complementary; - + double artifact_cbdl; + double level0_cbdl; + double level123_cbdl; + /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ static Settings* create (); diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc index b56ea840e..73948c1e2 100644 --- a/rtengine/simpleprocess.cc +++ b/rtengine/simpleprocess.cc @@ -309,7 +309,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p delete [] buffer; } // directional pyramid equalizer - if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) ipf.dirpyrequalizer (labView);//TODO: this is the luminance tonecurve, not the RGB one + if((params.colorappearance.enabled && !settings->autocielab) || !params.colorappearance.enabled) ipf.dirpyrequalizer (labView, 1);//TODO: this is the luminance tonecurve, not the RGB one //Colorappearance and tone-mapping associated @@ -357,8 +357,9 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p float** buffer = new float*[fh]; for (int i=0; iciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d); - else ipf.ciecam_02 (cieView, ada, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd); + int sk=1; + if(settings->ciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d, sk, 1); + else ipf.ciecam_02 (cieView, ada, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd, 1, 1); for (int i=0; iciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d); - else ipf.ciecam_02 (cieView, adap, begh, endh,1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd); + int sk=1; + if(settings->ciecamfloat) ipf.ciecam_02float (cieView, adap, begh, endh,1,2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, d, sk, 1); + else ipf.ciecam_02 (cieView, adap, begh, endh,1, 2, labView, ¶ms,customColCurve1,customColCurve2,customColCurve3, dummy, dummy, CAMBrightCurveJ, CAMBrightCurveQ, CAMMean, 5, 1, (float**)buffer, true, dd, 1, 1); for (int i=0; isetAdjusterBehavior (false,false); shadowshighlights->setAdjusterBehavior (false, false, false); - dirpyrequalizer->setAdjusterBehavior (false, false); + dirpyrequalizer->setAdjusterBehavior (false, false, false); dirpyrdenoise->setAdjusterBehavior (false, false,false,false,false,false); preprocess->setAdjusterBehavior (false, false); rawcacorrection->setAdjusterBehavior (false); @@ -176,7 +176,7 @@ void BatchToolPanelCoordinator::initSession () { chmixer->setAdjusterBehavior (options.baBehav[ADDSET_CHMIXER] ); blackwhite->setAdjusterBehavior (options.baBehav[ADDSET_BLACKWHITE_HUES],options.baBehav[ADDSET_BLACKWHITE_GAMMA]); shadowshighlights->setAdjusterBehavior (options.baBehav[ADDSET_SH_HIGHLIGHTS], options.baBehav[ADDSET_SH_SHADOWS], options.baBehav[ADDSET_SH_LOCALCONTRAST]); - dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ], options.baBehav[ADDSET_DIRPYREQ_THRESHOLD]); + dirpyrequalizer->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYREQ], options.baBehav[ADDSET_DIRPYREQ_THRESHOLD], options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]); dirpyrdenoise->setAdjusterBehavior (options.baBehav[ADDSET_DIRPYRDN_LUMA],options.baBehav[ADDSET_DIRPYRDN_LUMDET],options.baBehav[ADDSET_DIRPYRDN_CHROMA],options.baBehav[ADDSET_DIRPYRDN_CHROMARED],options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE], options.baBehav[ADDSET_DIRPYRDN_GAMMA]); preprocess->setAdjusterBehavior (options.baBehav[ADDSET_PREPROCESS_LINEDENOISE], options.baBehav[ADDSET_PREPROCESS_GREENEQUIL]); rawcacorrection->setAdjusterBehavior (options.baBehav[ADDSET_RAWCACORR]); @@ -262,6 +262,7 @@ void BatchToolPanelCoordinator::initSession () { if (options.baBehav[ADDSET_DIRPYREQ]) for (int i=0; i<5; i++) pparams.dirpyrequalizer.mult[i] = 0; if (options.baBehav[ADDSET_DIRPYREQ_THRESHOLD]) pparams.dirpyrequalizer.threshold = 0; + if (options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT]) pparams.dirpyrequalizer.skinprotect = 0; if (options.baBehav[ADDSET_DIRPYRDN_LUMA]) pparams.dirpyrDenoise.luma = 0; diff --git a/rtgui/coarsepanel.cc b/rtgui/coarsepanel.cc index a09bd8f3b..44e19d870 100644 --- a/rtgui/coarsepanel.cc +++ b/rtgui/coarsepanel.cc @@ -109,7 +109,11 @@ void CoarsePanel::initBatchBehavior () { void CoarsePanel::rotateLeft () { - degree = (degree + 270) % 360; + //Rotate one way or the opposite depending if the image is already flipped or not + if ( (vflip->get_active()) == (hflip->get_active ()) ) + degree = (degree + 270) % 360; + else + degree = (degree + 90) % 360; degreechanged = true; if (listener) listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); @@ -117,7 +121,11 @@ void CoarsePanel::rotateLeft () { void CoarsePanel::rotateRight () { - degree = (degree + 90) % 360; + //Rotate one way or the opposite depending if the image is already flipped or not + if ( (vflip->get_active()) == (hflip->get_active ()) ) + degree = (degree + 90) % 360; + else + degree = (degree + 270) % 360; degreechanged = true; if (listener) listener->panelChanged (EvCTRotate, Glib::ustring::format (degree)); diff --git a/rtgui/crop.cc b/rtgui/crop.cc index efc5aece0..27d60297e 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -497,32 +497,34 @@ void Crop::vFlipCrop () { g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); } -void Crop::rotateCrop (int deg) { - - int tmp; - switch ((360+deg-lastRotationDeg)%360) { - case 90: - tmp = nx; - nx = maxh - ny - nh; - ny = tmp; - tmp = nw; - nw = nh; - nh = tmp; - break; - case 270: - tmp = ny; - ny = maxw - nx - nw; - nx = tmp; - tmp = nw; - nw = nh; - nh = tmp; - break; - case 180: - nx = maxw - nx - nw; - ny = maxh - ny - nh; - break; - } +void Crop::rotateCrop (int deg, bool hflip, bool vflip) { + int rotation = (360+deg-lastRotationDeg)%360; + if((hflip != vflip) && ((rotation%180)==90)) + rotation = (rotation + 180)%360; + int tmp; + switch (rotation) { + case 90: + tmp = nx; + nx = maxh - ny - nh; + ny = tmp; + tmp = nw; + nw = nh; + nh = tmp; + break; + case 270: + tmp = ny; + ny = maxw - nx - nw; + nx = tmp; + tmp = nw; + nw = nh; + nh = tmp; + break; + case 180: + nx = maxw - nx - nw; + ny = maxh - ny - nh; + break; + } lastRotationDeg = deg; g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); } diff --git a/rtgui/crop.h b/rtgui/crop.h index 42f1bb7e4..31b12d15c 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -111,7 +111,7 @@ class Crop : public Gtk::VBox, public CropGUIListener, public FoldableToolPanel, void resizeScaleChanged (double rsc); void hFlipCrop (); void vFlipCrop (); - void rotateCrop (int deg); + void rotateCrop (int deg, bool hflip, bool vflip); }; #endif diff --git a/rtgui/dirpyrequalizer.cc b/rtgui/dirpyrequalizer.cc index 80942bf95..e6fe1f26c 100644 --- a/rtgui/dirpyrequalizer.cc +++ b/rtgui/dirpyrequalizer.cc @@ -26,6 +26,21 @@ DirPyrEqualizer::DirPyrEqualizer () : Gtk::VBox(), FoldableToolPanel(this) { set_border_width(4); + std::vector milestones; + + float r, g, b; + Color::hsv2rgb01(0.7500, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0. , r, g, b) ); // hsv: 0.75 rad: -0.9 + Color::hsv2rgb01(0.8560, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.1470, r, g, b) ); // hsv: 0.856 rad: -0.4 + Color::hsv2rgb01(0.9200, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.2353, r, g, b) ); // hsv: 0.92 rad: -0.1 + Color::hsv2rgb01(0.9300, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.2647, r, g, b) ); // hsv: 0.93 rad: 0 + Color::hsv2rgb01(0.9600, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.3380, r, g, b) ); // hsv: 0.96 rad: 0.25 + Color::hsv2rgb01(1.0000, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.4412, r, g, b) ); // hsv: 1. rad: 0.6 + Color::hsv2rgb01(0.0675, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.6176, r, g, b) ); // hsv: 0.0675 rad: 1.2 + Color::hsv2rgb01(0.0900, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.6764, r, g, b) ); // hsv: 0.09 rad: 1.4 + Color::hsv2rgb01(0.1700, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.7647, r, g, b) ); // hsv: 0.17 rad: 1.7 + Color::hsv2rgb01(0.2650, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(0.8824, r, g, b) ); // hsv: 0.265 rad: 2.1 + Color::hsv2rgb01(0.3240, 0.5, 0.5, r, g, b); milestones.push_back( GradientMilestone(1. , r, g, b) ); // hsv: 0.324 rad: 2.5 + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); enabled->set_active (true); pack_start(*enabled); @@ -73,8 +88,45 @@ DirPyrEqualizer::DirPyrEqualizer () : Gtk::VBox(), FoldableToolPanel(this) { threshold->setAdjusterListener(this); pack_start(*threshold); - show_all_children (); + Gtk::HSeparator *separator4 = Gtk::manage (new Gtk::HSeparator()); + pack_start(*separator4, Gtk::PACK_SHRINK, 2); +/* + algoHBox = Gtk::manage (new Gtk::HBox ()); + algoHBox->set_border_width (0); + algoHBox->set_spacing (2); + algoHBox->set_tooltip_markup (M("TP_DIRPYREQUALIZER_ALGO_TOOLTIP")); +*/ +// alLabel = Gtk::manage (new Gtk::Label (M("TP_DIRPYREQUALIZER_ALGO")+":")); +// algoHBox->pack_start (*alLabel, Gtk::PACK_SHRINK); +/* + algo = Gtk::manage (new MyComboBoxText ()); + algo->append_text (M("TP_DIRPYREQUALIZER_ALGO_FI")); + algo->append_text (M("TP_DIRPYREQUALIZER_ALGO_LA")); + algo->set_active (1); +// algoHBox->pack_start (*algo); +// pack_start(*algoHBox); + algoconn = algo->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrEqualizer::algoChanged) ); +*/ + skinprotect = Gtk::manage ( new Adjuster (M("TP_DIRPYREQUALIZER_SKIN"), -100, 100, 1, 0.) ); + skinprotect->setAdjusterListener(this); + pack_start(*skinprotect); + skinprotect->set_tooltip_markup (M("TP_DIRPYREQUALIZER_SKIN_TOOLTIP")); + hueskin = Gtk::manage (new ThresholdAdjuster (M("TP_DIRPYREQUALIZER_HUESKIN"), -40., 210., -5., 25., 170., 120., 0, false)); //default (b_l 0, t_l 30, b_r 170, t_r 120); + hueskin->set_tooltip_markup (M("TP_DIRPYREQUALIZER_HUESKIN_TOOLTIP")); + + hueskin->setBgGradient(milestones); + pack_start(*hueskin); + + gamutlab = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYREQUALIZER_GAMUT"))); + gamutlab->set_active (true); + pack_start(*gamutlab); + gamutlabConn = gamutlab->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrEqualizer::gamutlabToggled) ); + gamutlab->set_tooltip_markup (M("TP_DIRPYREQUALIZER_TOOLTIP")); + + hueskin->setAdjusterListener (this); + + show_all_children (); //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% } @@ -89,22 +141,42 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) { if (pedited) { enabled->set_inconsistent (!pedited->dirpyrequalizer.enabled); + gamutlab->set_inconsistent (!pedited->dirpyrequalizer.gamutlab); for(int i = 0; i < 5; i++) { multiplier[i]->setEditedState (pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); } threshold->setEditedState (pedited->dirpyrequalizer.threshold ? Edited : UnEdited); + skinprotect->setEditedState (pedited->dirpyrequalizer.skinprotect ? Edited : UnEdited); + hueskin->setEditedState (pedited->dirpyrequalizer.hueskin ? Edited : UnEdited); } enaConn.block (true); enabled->set_active (pp->dirpyrequalizer.enabled); enaConn.block (false); lastEnabled = pp->dirpyrequalizer.enabled; +/* + algoconn.block(true); + if (pedited && !pedited->dirpyrequalizer.algo) + algo->set_active (2); + else if (pp->dirpyrequalizer.algo=="FI") + algo->set_active (0); + else if (pp->dirpyrequalizer.algo=="LA") + algo->set_active (1); + algoconn.block(false); + algoChanged(); +*/ + gamutlabConn.block (true); + gamutlab->set_active (pp->dirpyrequalizer.gamutlab); + gamutlabConn.block (false); + lastgamutlab = pp->dirpyrequalizer.gamutlab; for (int i = 0; i < 5; i++) { multiplier[i]->setValue(pp->dirpyrequalizer.mult[i]); } threshold->setValue(pp->dirpyrequalizer.threshold); + skinprotect->setValue(pp->dirpyrequalizer.skinprotect); + hueskin->setValue(pp->dirpyrequalizer.hueskin); enableListener (); } @@ -112,44 +184,72 @@ void DirPyrEqualizer::read (const ProcParams* pp, const ParamsEdited* pedited) { void DirPyrEqualizer::write (ProcParams* pp, ParamsEdited* pedited) { pp->dirpyrequalizer.enabled = enabled->get_active (); + pp->dirpyrequalizer.gamutlab = gamutlab->get_active (); + pp->dirpyrequalizer.hueskin = hueskin->getValue (); for (int i = 0; i < 5; i++) { pp->dirpyrequalizer.mult[i] = multiplier[i]->getValue(); } pp->dirpyrequalizer.threshold = threshold->getValue(); + pp->dirpyrequalizer.skinprotect = skinprotect->getValue(); if (pedited) { pedited->dirpyrequalizer.enabled = !enabled->get_inconsistent(); + pedited->dirpyrequalizer.hueskin = hueskin->getEditedState (); for(int i = 0; i < 5; i++) { pedited->dirpyrequalizer.mult[i] = multiplier[i]->getEditedState(); } pedited->dirpyrequalizer.threshold = threshold->getEditedState(); + pedited->dirpyrequalizer.skinprotect = skinprotect->getEditedState(); + // pedited->dirpyrequalizer.algo = algo->get_active_text()!=M("GENERAL_UNCHANGED"); } +/* if (algo->get_active_row_number()==0) + pp->dirpyrequalizer.algo = "FI"; + else if (algo->get_active_row_number()==1) + pp->dirpyrequalizer.algo = "LA"; + */ } - +/* +void DirPyrEqualizer::algoChanged () { + if (listener && (multiImage||enabled->get_active()) ) { + listener->panelChanged (EvDirPyrEqualizeralg, algo->get_active_text ());} +} +*/ void DirPyrEqualizer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { for (int i = 0; i < 5; i++) { multiplier[i]->setDefault(defParams->dirpyrequalizer.mult[i]); } threshold->setDefault(defParams->dirpyrequalizer.threshold); - + hueskin->setDefault (defParams->dirpyrequalizer.hueskin); + if (pedited) { for (int i = 0; i < 5; i++) { multiplier[i]->setDefaultEditedState(pedited->dirpyrequalizer.mult[i] ? Edited : UnEdited); } threshold->setDefaultEditedState(pedited->dirpyrequalizer.threshold ? Edited : UnEdited); + skinprotect->setDefaultEditedState(pedited->dirpyrequalizer.skinprotect ? Edited : UnEdited); + hueskin->setDefaultEditedState (pedited->dirpyrequalizer.hueskin ? Edited : UnEdited); } else { for (int i = 0; i < 5; i++) { multiplier[i]->setDefaultEditedState(Irrelevant); } threshold->setDefaultEditedState(Irrelevant); + skinprotect->setDefaultEditedState(Irrelevant); + hueskin->setDefaultEditedState (Irrelevant); } } +void DirPyrEqualizer::adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight) { + if (listener && (multiImage||enabled->get_active()) ) { + listener->panelChanged (EvDirPyrEqualizerHueskin, hueskin->getHistoryString()); + } +} + + void DirPyrEqualizer::setBatchMode (bool batchMode) { ToolPanel::setBatchMode (batchMode); @@ -158,6 +258,9 @@ void DirPyrEqualizer::setBatchMode (bool batchMode) { multiplier[i]->showEditedCB(); } threshold->showEditedCB(); + skinprotect->showEditedCB(); + hueskin->showEditedCB (); + // algo->append_text (M("GENERAL_UNCHANGED")); } void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) { @@ -169,6 +272,12 @@ void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) { Glib::ustring::format(std::fixed, std::setprecision(2), threshold->getValue())) ); } + else if (a == skinprotect) { + listener->panelChanged (EvDirPyrEqualizerSkin, + Glib::ustring::compose("%1", + Glib::ustring::format(std::fixed, std::setprecision(2), skinprotect->getValue())) + ); + } else { listener->panelChanged (EvDirPyrEqualizer, Glib::ustring::compose("%1, %2, %3, %4, %5", @@ -179,7 +288,7 @@ void DirPyrEqualizer::adjusterChanged (Adjuster* a, double newval) { Glib::ustring::format(std::fixed, std::setprecision(2), multiplier[4]->getValue())) ); } - } + } } void DirPyrEqualizer::enabledToggled () { @@ -205,6 +314,28 @@ void DirPyrEqualizer::enabledToggled () { } } +void DirPyrEqualizer::gamutlabToggled () { + + if (batchMode) { + if (gamutlab->get_inconsistent()) { + gamutlab->set_inconsistent (false); + gamutlabConn.block (true); + gamutlab->set_active (false); + gamutlabConn.block (false); + } + else if (lastgamutlab) + gamutlab->set_inconsistent (true); + + lastgamutlab = gamutlab->get_active (); + } + + if (listener) { + if (gamutlab->get_active ()) + listener->panelChanged (EvDirPyrEqlgamutlab, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDirPyrEqlgamutlab, M("GENERAL_DISABLED")); + } +} void DirPyrEqualizer::lumaneutralPressed () { @@ -234,11 +365,12 @@ void DirPyrEqualizer::lumacontrastMinusPressed () { } } -void DirPyrEqualizer::setAdjusterBehavior (bool multiplieradd, bool thresholdadd) { +void DirPyrEqualizer::setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool skinadd) { for (int i=0; i<5; i++) multiplier[i]->setAddMode(multiplieradd); threshold->setAddMode(thresholdadd); + skinprotect->setAddMode(skinadd); } void DirPyrEqualizer::trimValues (rtengine::procparams::ProcParams* pp) { @@ -246,4 +378,5 @@ void DirPyrEqualizer::trimValues (rtengine::procparams::ProcParams* pp) { for (int i=0; i<5; i++) multiplier[i]->trimValue(pp->dirpyrequalizer.mult[i]); threshold->trimValue(pp->dirpyrequalizer.threshold); + skinprotect->trimValue(pp->dirpyrequalizer.skinprotect); } diff --git a/rtgui/dirpyrequalizer.h b/rtgui/dirpyrequalizer.h index 60783f92f..d91ac70eb 100644 --- a/rtgui/dirpyrequalizer.h +++ b/rtgui/dirpyrequalizer.h @@ -23,22 +23,31 @@ #include #include "adjuster.h" #include "toolpanel.h" +#include "thresholdadjuster.h" +#include "colorprovider.h" -class DirPyrEqualizer : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel +class DirPyrEqualizer : public Gtk::VBox, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel { protected: Gtk::CheckButton * enabled; + Gtk::CheckButton * gamutlab; Adjuster* multiplier[5]; Adjuster* threshold; + Adjuster* skinprotect; + ThresholdAdjuster* hueskin; + // MyComboBoxText* algo; + // sigc::connection algoconn; + // Gtk::Label* alLabel; + // Gtk::HBox* algoHBox; - sigc::connection enaConn; + sigc::connection enaConn, gamutlabConn; sigc::connection lumaneutralPressedConn; sigc::connection lumacontrastPlusPressedConn; sigc::connection lumacontrastMinusPressedConn; - - bool lastEnabled; + + bool lastEnabled, lastgamutlab; public: @@ -49,11 +58,14 @@ public: void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL); void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL); void setBatchMode (bool batchMode); - void setAdjusterBehavior (bool multiplieradd, bool thresholdadd); + void setAdjusterBehavior (bool multiplieradd, bool thresholdadd, bool skinadd); void trimValues (rtengine::procparams::ProcParams* pp); + void adjusterChanged (ThresholdAdjuster* a, int newBottomLeft, int newTopLeft, int newBottomRight, int newTopRight); +// void algoChanged (); void adjusterChanged (Adjuster* a, double newval); void enabledToggled (); + void gamutlabToggled (); void lumaneutralPressed (); void lumacontrastPlusPressed (); void lumacontrastMinusPressed (); diff --git a/rtgui/options.cc b/rtgui/options.cc index 0bb72a387..44a5007e0 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -436,8 +436,6 @@ void Options::setDefaults () { 0, // ADDSET_DIRPYRDN_CHROMABLUE 0, // ADDSET_DIRPYRDN_GAMMA 0, // ADDSET_CHMIXER - 0, // ADDSET_BLACKWHITE_HUES - 0, // ADDSET_BLACKWHITE_GAMMA 0, // ADDSET_PREPROCESS_GREENEQUIL 0, // ADDSET_PREPROCESS_LINEDENOISE 0, // ADDSET_RAWCACORR @@ -455,10 +453,16 @@ void Options::setDefaults () { 0, // ADDSET_CAT_DEGREE 0, // ADDSET_CAT_ADAPSCEN 0, // ADDSET_CAT_ADAPLUM + 0, // ADDSET_CAT_LIGHT + 0, // ADDSET_CAT_RSTPRO 0, // ADDSET_CAT_BADPIX 0, // ADDSET_CAT_JLIGHT 0, // ADDSET_CAT_CHROMA 0, // ADDSET_CAT_CONTRAST + 0, // ADDSET_CAT_CHROMA_S + 0, // ADDSET_CAT_CHROMA_M + 0, // ADDSET_CAT_HUE + 0, // ADDSET_CAT_BADPIX 0, // ADDSET_WB_EQUAL 0, // ADDSET_GRADIENT_DEGREE 0, // ADDSET_GRADIENT_FEATHER @@ -467,6 +471,10 @@ void Options::setDefaults () { 0, // ADDSET_PCVIGNETTE_STRENGTH 0, // ADDSET_PCVIGNETTE_FEATHER 0, // ADDSET_PCVIGNETTE_ROUNDNESS + 0, // ADDSET_BLACKWHITE_HUES + 0, // ADDSET_BLACKWHITE_GAMMA + 0, // ADDSET_DIRPYREQ_THRESHOLD + 0, // ADDSET_DIRPYREQ_SKINPROTECT }; baBehav = std::vector (babehav, babehav+ADDSET_PARAM_NUM); @@ -503,6 +511,9 @@ void Options::setDefaults () { rtSettings.gamutICC = true; rtSettings.gamutLch = true; rtSettings.amchroma = 40;//between 20 and 140 low values increase effect..and also artefacts, high values reduces + rtSettings.artifact_cbdl = 4.; + rtSettings.level0_cbdl = 0; + rtSettings.level123_cbdl = 30; rtSettings.ciecamfloat = true; rtSettings.protectred = 60; @@ -733,6 +744,9 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "CRI")) rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI"); if (keyFile.has_key ("Color Management", "view")) rtSettings.viewingdevice = keyFile.get_integer("Color Management", "view"); if (keyFile.has_key ("Color Management", "grey")) rtSettings.viewingdevicegrey = keyFile.get_integer("Color Management", "grey"); + if (keyFile.has_key ("Color Management", "CBDLArtif")) rtSettings.artifact_cbdl = keyFile.get_double("Color Management", "CBDLArtif"); + if (keyFile.has_key ("Color Management", "CBDLlevel0")) rtSettings.level0_cbdl = keyFile.get_double("Color Management", "CBDLlevel0"); + if (keyFile.has_key ("Color Management", "CBDLlevel123")) rtSettings.level123_cbdl = keyFile.get_double("Color Management", "CBDLlevel123"); if (keyFile.has_key ("Color Management", "WhiteBalanceSpotSize")) whiteBalanceSpotSize = keyFile.get_integer("Color Management", "WhiteBalanceSpotSize"); if( keyFile.has_key ("Color Management", "GamutICC")) rtSettings.gamutICC = keyFile.get_boolean("Color Management", "GamutICC"); @@ -1033,6 +1047,10 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); keyFile.set_integer ("Color Management", "CRI", rtSettings.CRI_color); // keyFile.set_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); + keyFile.set_double ("Color Management", "CBDLArtif", rtSettings.artifact_cbdl); + keyFile.set_double ("Color Management", "CBDLlevel0", rtSettings.level0_cbdl); + keyFile.set_double ("Color Management", "CBDLlevel123", rtSettings.level123_cbdl); + Glib::ArrayHandle bab = baBehav; keyFile.set_integer_list ("Batch Processing", "AdjusterBehavior", bab); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 00051ce82..72e26921a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -291,10 +291,14 @@ void ParamsEdited::set (bool v) { raw.exTwoGreen=v; dirpyrequalizer.enabled = v; + dirpyrequalizer.gamutlab = v; for(int i = 0; i < 5; i++) { dirpyrequalizer.mult[i] = v; } dirpyrequalizer.threshold = v; + dirpyrequalizer.skinprotect = v; + dirpyrequalizer.hueskin = v; + //dirpyrequalizer.algo = v; hsvequalizer.hcurve = v; hsvequalizer.scurve = v; hsvequalizer.vcurve = v; @@ -575,10 +579,14 @@ void ParamsEdited::initFrom (const std::vector raw.exTwoGreen = p.raw.twogreen == other.raw.twogreen; dirpyrequalizer.enabled = dirpyrequalizer.enabled && p.dirpyrequalizer.enabled == other.dirpyrequalizer.enabled; + dirpyrequalizer.gamutlab = dirpyrequalizer.gamutlab && p.dirpyrequalizer.gamutlab == other.dirpyrequalizer.gamutlab; for(int i = 0; i < 5; i++) { dirpyrequalizer.mult[i] = dirpyrequalizer.mult[i] && p.dirpyrequalizer.mult[i] == other.dirpyrequalizer.mult[i]; } dirpyrequalizer.threshold = dirpyrequalizer.threshold && p.dirpyrequalizer.threshold == other.dirpyrequalizer.threshold; + dirpyrequalizer.skinprotect = dirpyrequalizer.skinprotect && p.dirpyrequalizer.skinprotect == other.dirpyrequalizer.skinprotect; + // dirpyrequalizer.algo = dirpyrequalizer.algo && p.dirpyrequalizer.algo == other.dirpyrequalizer.algo; + dirpyrequalizer.hueskin = dirpyrequalizer.hueskin && p.dirpyrequalizer.hueskin == other.dirpyrequalizer.hueskin; hsvequalizer.hcurve = hsvequalizer.hcurve && p.hsvequalizer.hcurve == other.hsvequalizer.hcurve; hsvequalizer.scurve = hsvequalizer.scurve && p.hsvequalizer.scurve == other.hsvequalizer.scurve; hsvequalizer.vcurve = hsvequalizer.vcurve && p.hsvequalizer.vcurve == other.hsvequalizer.vcurve; @@ -861,10 +869,14 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (raw.ff_BlurType) toEdit.raw.ff_BlurType = mods.raw.ff_BlurType; if (dirpyrequalizer.enabled) toEdit.dirpyrequalizer.enabled = mods.dirpyrequalizer.enabled; + if (dirpyrequalizer.gamutlab) toEdit.dirpyrequalizer.gamutlab = mods.dirpyrequalizer.gamutlab; for(int i = 0; i < 5; i++) { if(dirpyrequalizer.mult[i]) toEdit.dirpyrequalizer.mult[i] = dontforceSet && options.baBehav[ADDSET_DIRPYREQ] ? toEdit.dirpyrequalizer.mult[i] + mods.dirpyrequalizer.mult[i] : mods.dirpyrequalizer.mult[i]; } if (dirpyrequalizer.threshold) toEdit.dirpyrequalizer.threshold= dontforceSet && options.baBehav[ADDSET_DIRPYREQ_THRESHOLD] ? toEdit.dirpyrequalizer.threshold + mods.dirpyrequalizer.threshold : mods.dirpyrequalizer.threshold; + if (dirpyrequalizer.skinprotect)toEdit.dirpyrequalizer.skinprotect= dontforceSet && options.baBehav[ADDSET_DIRPYREQ_SKINPROTECT] ? toEdit.dirpyrequalizer.skinprotect + mods.dirpyrequalizer.skinprotect : mods.dirpyrequalizer.skinprotect; + if (dirpyrequalizer.hueskin) toEdit.dirpyrequalizer.hueskin = mods.dirpyrequalizer.hueskin; +// if (dirpyrequalizer.algo) toEdit.dirpyrequalizer.algo = mods.dirpyrequalizer.algo; if (hsvequalizer.hcurve) toEdit.hsvequalizer.hcurve = mods.hsvequalizer.hcurve; if (hsvequalizer.scurve) toEdit.hsvequalizer.scurve = mods.hsvequalizer.scurve; if (hsvequalizer.vcurve) toEdit.hsvequalizer.vcurve = mods.hsvequalizer.vcurve; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 46cf41262..5836846fa 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -434,8 +434,12 @@ class DirPyrEqualizerParamsEdited { public: bool enabled; + bool gamutlab; bool mult[5]; bool threshold; + bool skinprotect; + bool hueskin; + // bool algo; }; class HSVEqualizerParamsEdited { diff --git a/rtgui/ppversion.h b/rtgui/ppversion.h index c8ef25791..e6d4e426a 100644 --- a/rtgui/ppversion.h +++ b/rtgui/ppversion.h @@ -2,11 +2,13 @@ #define _PPVERSION_ // This number has to be incremented whenever the PP3 file format is modified or the behaviour of a tool changes -#define PPVERSION 318 +#define PPVERSION 319 #define PPVERSION_AEXP 301 //value of PPVERSION when auto exposure algorithm was modified /* - Log of version changes + Log of version changes + 319 2014-02-11 + Hue skin for Contrast by detail levels 318 2014-02-10 Vignetting Correction bug makes hard transitions for positive Amount values, Issue 2241 317 2014-01-19 diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index d6aaf8bc5..9214d8127 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -281,6 +281,7 @@ Gtk::Widget* Preferences::getBatchProcPanel () { mi->set_value (behavColumns.label, M("TP_DIRPYREQUALIZER_LABEL")); appendBehavList (mi, M("TP_EXPOSURE_CONTRAST"), ADDSET_DIRPYREQ, true); appendBehavList (mi, M("TP_DIRPYREQUALIZER_THRESHOLD"), ADDSET_DIRPYREQ_THRESHOLD, true); + appendBehavList (mi, M("TP_DIRPYREQUALIZER_SKIN"), ADDSET_DIRPYREQ_SKINPROTECT, true); mi = behModel->append (); mi->set_value (behavColumns.label, M("TP_PREPROCESS_LABEL")); diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index f2d408f66..9f3d6667e 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -254,7 +254,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib:: crop->write (params); } else if (event==rtengine::EvCTRotate) { - crop->rotateCrop (params->coarse.rotate); + crop->rotateCrop (params->coarse.rotate, params->coarse.hflip, params->coarse.vflip); crop->write (params); resize->update (params->crop.enabled, params->crop.w, params->crop.h, ipc->getFullWidth(), ipc->getFullHeight()); resize->write (params);