diff --git a/rtdata/languages/Polish b/rtdata/languages/Polish
index 26be7fb2b..1393c2aa7 100644
--- a/rtdata/languages/Polish
+++ b/rtdata/languages/Polish
@@ -1598,11 +1598,25 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: -
!HISTORY_MSG_368;W - Final - Contrast balance
!HISTORY_MSG_369;W - Final - Balance method
!HISTORY_MSG_370;W - Final - Local contrast curve
+!HISTORY_MSG_371;Post-Resize Sharpening
+!HISTORY_MSG_372;PRS USM - Radius
+!HISTORY_MSG_373;PRS USM - Amount
+!HISTORY_MSG_374;PRS USM - Threshold
+!HISTORY_MSG_375;PRS USM - Sharpen only edges
+!HISTORY_MSG_376;PRS USM - Edge detection radius
+!HISTORY_MSG_377;PRS USM - Edge tolerance
+!HISTORY_MSG_378;PRS USM - Halo control
+!HISTORY_MSG_379;PRS USM - Halo control amount
+!HISTORY_MSG_380;PRS - Method
+!HISTORY_MSG_381;PRS RLD - Radius
+!HISTORY_MSG_382;PRS RLD - Amount
+!HISTORY_MSG_383;PRS RLD - Damping
+!HISTORY_MSG_384;PRS RLD - Iterations
!MAIN_TAB_INSPECT; Inspect
!MAIN_TAB_WAVELET;Wavelet
!MAIN_TAB_WAVELET_TOOLTIP;Shortcut: Alt-w
-!PARTIALPASTE_EQUALIZER;Wavelet Equalizer
-!PARTIALPASTE_WAVELETGROUP;Wavelet processing
+!PARTIALPASTE_EQUALIZER;Wavelet levels
+!PARTIALPASTE_WAVELETGROUP;Wavelet Levels
!PREFERENCES_AUTLISLOW;Low
!PREFERENCES_AUTLISMAX;Max - Average of all tiles
!PREFERENCES_AUTLISSTD;High
@@ -1693,6 +1707,8 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: -
!TP_EPD_GAMMA;Gamma
!TP_EXPOSURE_TCMODE_LUMINANCE;Luminance
!TP_ICM_SAVEREFERENCE_APPLYWB;Apply white balance
+!TP_PRSHARPENING_LABEL;Post-Resize Sharpening
+!TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions.
!TP_RAW_HD;Threshold
!TP_RAW_HD_TOOLTIP;Lower values make hot/dead pixel detection more aggressive, but false positives may lead to artifacts. If you notice any artifacts appearing when enabling the Hot/Dead Pixel Filters, gradually increase the threshold value until they disappear.
!TP_WAVELET_1;Level 1
@@ -1788,10 +1804,10 @@ ZOOMPANEL_ZOOMOUT;Oddal\nSkrót: -
!TP_WAVELET_INF;Below or equal the level
!TP_WAVELET_ITER;Delta balance levels
!TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels.
-!TP_WAVELET_LABEL;Wavelet levels
+!TP_WAVELET_LABEL;Wavelet Levels
!TP_WAVELET_LARGEST;Coarsest
!TP_WAVELET_LEVCH;Chromaticity
-!TP_WAVELET_LEVELS;Wavelet levels
+!TP_WAVELET_LEVELS;Wavelet Levels
!TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time.
!TP_WAVELET_LEVF;Contrast
!TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1
diff --git a/rtdata/languages/default b/rtdata/languages/default
index e9c87e10e..82f42a6c4 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -235,15 +235,15 @@ HISTORY_MSG_1;Photo loaded
HISTORY_MSG_2;PP3 loaded
HISTORY_MSG_3;PP3 changed
HISTORY_MSG_4;History browsing
-HISTORY_MSG_5;Lightness
-HISTORY_MSG_6;Contrast
-HISTORY_MSG_7;Black
-HISTORY_MSG_8;Exposure compensation
-HISTORY_MSG_9;Highlight compression
-HISTORY_MSG_10;Shadow compression
-HISTORY_MSG_11;Tone curve 1
-HISTORY_MSG_12;Auto levels
-HISTORY_MSG_13;Exposure clipping
+HISTORY_MSG_5;Exposure - Lightness
+HISTORY_MSG_6;Exposure - Contrast
+HISTORY_MSG_7;Exposure - Black
+HISTORY_MSG_8;Exposure - Compensation
+HISTORY_MSG_9;Exposure - Highlight compression
+HISTORY_MSG_10;Exposure - Shadow compression
+HISTORY_MSG_11;Exposure - Tone curve 1
+HISTORY_MSG_12;Exposure - Auto levels
+HISTORY_MSG_13;Exposure - Clip
HISTORY_MSG_14;L*a*b* - Lightness
HISTORY_MSG_15;L*a*b* - Contrast
HISTORY_MSG_16;-
@@ -259,7 +259,7 @@ HISTORY_MSG_25;USM - Edge detection radius
HISTORY_MSG_26;USM - Edge tolerance
HISTORY_MSG_27;USM - Halo control
HISTORY_MSG_28;USM - Halo control amount
-HISTORY_MSG_29;Sharpening method
+HISTORY_MSG_29;Sharpening - Method
HISTORY_MSG_30;RLD - Radius
HISTORY_MSG_31;RLD - Amount
HISTORY_MSG_32;RLD - Damping
@@ -267,13 +267,13 @@ HISTORY_MSG_33;RLD - Iterations
HISTORY_MSG_34;LCP distortion correction
HISTORY_MSG_35;LCP vignetting correction
HISTORY_MSG_36;LCP CA correction
-HISTORY_MSG_37;Auto levels
-HISTORY_MSG_38;White balance method
+HISTORY_MSG_37;Exposure - Auto levels
+HISTORY_MSG_38;White Balance - Method
HISTORY_MSG_39;WB - Temperature
HISTORY_MSG_40;WB - Tint
-HISTORY_MSG_41;Tone curve 1 mode
-HISTORY_MSG_42;Tone curve 2
-HISTORY_MSG_43;Tone curve 2 mode
+HISTORY_MSG_41;Exposure - Tone curve 1 mode
+HISTORY_MSG_42;Exposure - Tone curve 2
+HISTORY_MSG_43;Exposure - Tone curve 2 mode
HISTORY_MSG_44;Lum. denoising radius
HISTORY_MSG_45;Lum. denoising edge tolerance
HISTORY_MSG_46;Color denoising
@@ -283,8 +283,8 @@ HISTORY_MSG_49;DCP illuminant
HISTORY_MSG_50;Shadows/Highlights
HISTORY_MSG_51;S/H - Highlights
HISTORY_MSG_52;S/H - Shadows
-HISTORY_MSG_53;S/H - Highlight tonal width
-HISTORY_MSG_54;S/H - Shadow tonal width
+HISTORY_MSG_53;S/H - Highlights tonal width
+HISTORY_MSG_54;S/H - Shadows tonal width
HISTORY_MSG_55;S/H - Local contrast
HISTORY_MSG_56;S/H - Radius
HISTORY_MSG_57;Coarse rotation
@@ -296,9 +296,9 @@ HISTORY_MSG_62;Distortion correction
HISTORY_MSG_63;Snapshot selected
HISTORY_MSG_64;Crop
HISTORY_MSG_65;CA correction
-HISTORY_MSG_66;Highlight reconstruction
-HISTORY_MSG_67;HR reconstruction amount
-HISTORY_MSG_68;HL reconstruction method
+HISTORY_MSG_66;Exposure - Highlight reconstruction
+HISTORY_MSG_67;Exposure - HLR amount
+HISTORY_MSG_68;Exposure - HLR method
HISTORY_MSG_69;Working color space
HISTORY_MSG_70;Output color space
HISTORY_MSG_71;Input color space
@@ -316,8 +316,8 @@ HISTORY_MSG_82;Profile changed
HISTORY_MSG_83;S/H - Sharp mask
HISTORY_MSG_84;Perspective correction
HISTORY_MSG_85;LCP
-HISTORY_MSG_86;RGB curves - Luminosity mode
-HISTORY_MSG_87;Impulse noise reduction
+HISTORY_MSG_86;RGB Curves - Luminosity mode
+HISTORY_MSG_87;Impulse Noise Reduction
HISTORY_MSG_88;Impulse NR threshold
HISTORY_MSG_89;Noise Reduction
HISTORY_MSG_90;NR - Luminance
@@ -330,7 +330,7 @@ HISTORY_MSG_96;L*a*b* - a* curve
HISTORY_MSG_97;L*a*b* - b* curve
HISTORY_MSG_98;Demosaicing method
HISTORY_MSG_99;Hot pixel filter
-HISTORY_MSG_100;RGB Saturation
+HISTORY_MSG_100;Exposure - Saturation
HISTORY_MSG_101;HSV - Hue
HISTORY_MSG_102;HSV - Saturation
HISTORY_MSG_103;HSV - Value
@@ -338,7 +338,7 @@ HISTORY_MSG_104;HSV Equalizer
HISTORY_MSG_105;Defringe
HISTORY_MSG_106;Defringe - Radius
HISTORY_MSG_107;Defringe - Threshold
-HISTORY_MSG_108;Highlight Compr. Threshold
+HISTORY_MSG_108;Exposure - HLC threshold
HISTORY_MSG_109;Resize - Bounding box
HISTORY_MSG_110;Resize - Applies to
HISTORY_MSG_111;L*a*b* - Avoid color shift
@@ -393,10 +393,10 @@ HISTORY_MSG_159;TM - Edge stopping
HISTORY_MSG_160;TM - Scale
HISTORY_MSG_161;TM - Reweighting iterates
HISTORY_MSG_162;Tone Mapping
-HISTORY_MSG_163;RGB curves - Red
-HISTORY_MSG_164;RGB curves - Green
-HISTORY_MSG_165;RGB curves - Blue
-HISTORY_MSG_166;Neutral levels
+HISTORY_MSG_163;RGB Curves - Red
+HISTORY_MSG_164;RGB Curves - Green
+HISTORY_MSG_165;RGB Curves - Blue
+HISTORY_MSG_166;Exposure - Neutral
HISTORY_MSG_167;--unused--
HISTORY_MSG_168;L*a*b* - CC curve
HISTORY_MSG_169;L*a*b* - CH curve
@@ -425,7 +425,7 @@ HISTORY_MSG_191;CAM02 - Colorfulness (M)
HISTORY_MSG_192;CAM02 - Hue (h)
HISTORY_MSG_193;CAM02 - Tone curve 1
HISTORY_MSG_194;CAM02 - Tone curve 2
-HISTORY_MSG_195;CAM02 - Tone curve 1
+HISTORY_MSG_195;CAM02 - Tone curve 1
HISTORY_MSG_196;CAM02 - Tone curve 2
HISTORY_MSG_197;CAM02 - Color curve
HISTORY_MSG_198;CAM02 - Color curve
@@ -600,6 +600,20 @@ HISTORY_MSG_367;W - ES - Local contrast curve
HISTORY_MSG_368;W - Final - Contrast balance
HISTORY_MSG_369;W - Final - Balance method
HISTORY_MSG_370;W - Final - Local contrast curve
+HISTORY_MSG_371;Post-Resize Sharpening
+HISTORY_MSG_372;PRS USM - Radius
+HISTORY_MSG_373;PRS USM - Amount
+HISTORY_MSG_374;PRS USM - Threshold
+HISTORY_MSG_375;PRS USM - Sharpen only edges
+HISTORY_MSG_376;PRS USM - Edge detection radius
+HISTORY_MSG_377;PRS USM - Edge tolerance
+HISTORY_MSG_378;PRS USM - Halo control
+HISTORY_MSG_379;PRS USM - Halo control amount
+HISTORY_MSG_380;PRS - Method
+HISTORY_MSG_381;PRS RLD - Radius
+HISTORY_MSG_382;PRS RLD - Amount
+HISTORY_MSG_383;PRS RLD - Damping
+HISTORY_MSG_384;PRS RLD - Iterations
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOTS;Snapshots
@@ -732,12 +746,12 @@ OPTIONS_DEFIMG_MISSING;The default profile for non-raw photos could not b
OPTIONS_DEFRAW_MISSING;The default profile for raw photos could not be found or is not set.\n\nPlease check your profiles' directory, it may be missing or damaged.\n\nDefault internal values will be used.
PARTIALPASTE_BASICGROUP;Basic Settings
PARTIALPASTE_CACORRECTION;Chromatic aberration correction
-PARTIALPASTE_CHANNELMIXERBW;Black-and-White
+PARTIALPASTE_CHANNELMIXERBW;Black-and-white
PARTIALPASTE_CHANNELMIXER;Channel mixer
-PARTIALPASTE_COARSETRANS;Coarse rotation / flipping
+PARTIALPASTE_COARSETRANS;Coarse rotation/flipping
PARTIALPASTE_COLORAPP;CIECAM02
PARTIALPASTE_COLORGROUP;Color Related Settings
-PARTIALPASTE_COLORTONING;Color Toning
+PARTIALPASTE_COLORTONING;Color toning
PARTIALPASTE_COMMONTRANSFORMPARAMS;Auto-fill
PARTIALPASTE_COMPOSITIONGROUP;Composition Settings
PARTIALPASTE_CROP;Crop
@@ -750,11 +764,11 @@ PARTIALPASTE_DIRPYRDENOISE;Noise reduction
PARTIALPASTE_DIRPYREQUALIZER;Contrast by detail levels
PARTIALPASTE_DISTORTION;Distortion correction
PARTIALPASTE_EPD;Tone mapping
-PARTIALPASTE_EQUALIZER;Wavelet Equalizer
+PARTIALPASTE_EQUALIZER;Wavelet levels
PARTIALPASTE_EVERYTHING;Everything
PARTIALPASTE_EXIFCHANGES;Exif
PARTIALPASTE_EXPOSURE;Exposure
-PARTIALPASTE_FILMSIMULATION;Film Simulation
+PARTIALPASTE_FILMSIMULATION;Film simulation
PARTIALPASTE_FLATFIELDAUTOSELECT;Flat-field auto-selection
PARTIALPASTE_FLATFIELDBLURRADIUS;Flat-field blur radius
PARTIALPASTE_FLATFIELDBLURTYPE;Flat-field blur type
@@ -767,7 +781,7 @@ PARTIALPASTE_ICMSETTINGS;Color management settings
PARTIALPASTE_IMPULSEDENOISE;Impulse noise reduction
PARTIALPASTE_IPTCINFO;IPTC
PARTIALPASTE_LABCURVE;L*a*b* adjustments
-PARTIALPASTE_LENSGROUP;Lens related settings
+PARTIALPASTE_LENSGROUP;Lens Related Settings
PARTIALPASTE_LENSPROFILE;Lens correction profile
PARTIALPASTE_METAGROUP;Metadata
PARTIALPASTE_PCVIGNETTE;Vignette filter
@@ -784,9 +798,9 @@ PARTIALPASTE_RAWEXPOS_LINEAR;White point correction
PARTIALPASTE_RAWEXPOS_PRESER;Highlight preservation
PARTIALPASTE_RAWGROUP;Raw Settings
PARTIALPASTE_RAW_DCBENHANCE;DCB enhancement
-PARTIALPASTE_RAW_DCBITERATIONS;Number of DCB iterations
+PARTIALPASTE_RAW_DCBITERATIONS;DCB iterations
PARTIALPASTE_RAW_DMETHOD;Demosaic method
-PARTIALPASTE_RAW_FALSECOLOR;Demosaic false color suppression steps
+PARTIALPASTE_RAW_FALSECOLOR;False color suppression
PARTIALPASTE_RAW_LMMSEITERATIONS;LMMSE enhancement steps
PARTIALPASTE_RESIZE;Resize
PARTIALPASTE_RGBCURVES;RGB curves
@@ -797,7 +811,7 @@ PARTIALPASTE_SHARPENING;Sharpening (USM/RL)
PARTIALPASTE_SHARPENMICRO;Microcontrast
PARTIALPASTE_VIBRANCE;Vibrance
PARTIALPASTE_VIGNETTING;Vignetting correction
-PARTIALPASTE_WAVELETGROUP;Wavelet processing
+PARTIALPASTE_WAVELETGROUP;Wavelet Levels
PARTIALPASTE_WHITEBALANCE;White balance
PREFERENCES_ADD;Add
PREFERENCES_APPLNEXTSTARTUP;restart required
@@ -1521,6 +1535,8 @@ TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels.
TP_PREPROCESS_LABEL;Preprocessing
TP_PREPROCESS_LINEDENOISE;Line noise filter
TP_PREPROCESS_NO_FOUND;None found
+TP_PRSHARPENING_LABEL;Post-Resize Sharpening
+TP_PRSHARPENING_TOOLTIP;Sharpens the image after resizing. Only works when the "Lanczos" resizing method is used. It is impossible to preview the effects of this tool. See RawPedia for usage instructions.
TP_RAWCACORR_AUTO;Auto-correction
TP_RAWCACORR_CABLUE;Blue
TP_RAWCACORR_CARED;Red
@@ -1578,7 +1594,7 @@ TP_ROTATE_SELECTLINE;Select Straight Line
TP_SAVEDIALOG_OK_TIP;Shortcut: Ctrl-Enter
TP_SHADOWSHLIGHTS_HIGHLIGHTS;Highlights
TP_SHADOWSHLIGHTS_HLTONALW;Highlights tonal width
-TP_SHADOWSHLIGHTS_LABEL;Shadows/highlights
+TP_SHADOWSHLIGHTS_LABEL;Shadows/Highlights
TP_SHADOWSHLIGHTS_LOCALCONTR;Local contrast
TP_SHADOWSHLIGHTS_RADIUS;Radius
TP_SHADOWSHLIGHTS_SHADOWS;Shadows
@@ -1725,10 +1741,10 @@ TP_WAVELET_HUESKY_TOOLTIP;The bottom points set the beginning of the transition
TP_WAVELET_INF;Below or equal the level
TP_WAVELET_ITER;Delta balance levels
TP_WAVELET_ITER_TOOLTIP;Left: increase low levels and reduce high levels,\nRight: reduce low levels and increase high levels.
-TP_WAVELET_LABEL;Wavelet levels
+TP_WAVELET_LABEL;Wavelet Levels
TP_WAVELET_LARGEST;Coarsest
TP_WAVELET_LEVCH;Chromaticity
-TP_WAVELET_LEVELS;Wavelet levels
+TP_WAVELET_LEVELS;Wavelet Levels
TP_WAVELET_LEVELS_TOOLTIP;Choose the number of detail levels the image is to be decomposed into. More levels require more RAM and require a longer processing time.
TP_WAVELET_LEVF;Contrast
TP_WAVELET_LEVLABEL;Preview maximum possible levels = %1
diff --git a/rtengine/alignedbuffer.h b/rtengine/alignedbuffer.h
index 3c048ad6e..5f8ced38f 100644
--- a/rtengine/alignedbuffer.h
+++ b/rtengine/alignedbuffer.h
@@ -145,14 +145,14 @@ public:
}
~AlignedBufferMP() {
- for (int i=0;i* acquire() {
MyMutex::MyLock lock(mtx);
// Find available buffer
- for (int i=0;iinUse) {
buffers[i]->inUse=true;
return buffers[i];
diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc
index c0ac11fbd..7220cfcd5 100644
--- a/rtengine/dcrop.cc
+++ b/rtengine/dcrop.cc
@@ -646,7 +646,7 @@ void Crop::update (int todo) {
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.sharpening (labnCrop, (float**)cbuffer, params.sharpening);
}
}
// if (skip==1) {
diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h
index e2e958fcb..c13428a67 100644
--- a/rtengine/improcfun.h
+++ b/rtengine/improcfun.h
@@ -68,7 +68,7 @@ class ImProcFunctions {
void transformLuminanceOnly (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int oW, int oH, int fW, int fH);
void transformHighQuality (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH, const LCPMapper *pLCPMap, bool fullImage);
- void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H);
+ void sharpenHaloCtrl (LabImage* lab, float** blurmap, float** base, int W, int H, SharpeningParams &sharpenParam);
void sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float** base, int W, int H);
void firstAnalysisThread(Imagefloat* original, Glib::ustring wprofile, unsigned int* histogram, int row_from, int row_to);
void dcdamping (float** aI, float** aO, float damping, int W, int H);
@@ -246,7 +246,7 @@ class ImProcFunctions {
void chromiLuminanceCurve (EditBuffer *editBuffer, int pW, LabImage* lold, LabImage* lnew, LUTf &acurve, LUTf &bcurve, LUTf & satcurve,LUTf & satclcurve, LUTf &clcurve, LUTf &curve, bool utili, bool autili, bool butili, bool ccutili, bool cclutili, bool clcutili, LUTu &histCCurve, LUTu &histCLurve, LUTu &histLCurve, LUTu &histLurve);
void vibrance (LabImage* lab);//Jacques' vibrance
void colorCurve (LabImage* lold, LabImage* lnew);
- void sharpening (LabImage* lab, float** buffer);
+ void sharpening (LabImage* lab, float** buffer, SharpeningParams &sharpenParam);
void sharpeningcam (CieImage* ncie, float** buffer);
void transform (Imagefloat* original, Imagefloat* transformed, int cx, int cy, int sx, int sy, int oW, int oH, int fW, int fH,
double focalLen, double focalLen35mm, float focusDist, int rawRotationDeg, bool fullImage);
@@ -256,7 +256,7 @@ class ImProcFunctions {
void Lanczos (const LabImage* src, LabImage* dst, float scale);
void Lanczos (const Image16* src, Image16* dst, float scale);
- void deconvsharpening (LabImage* lab, float** buffer);
+ void deconvsharpening (LabImage* lab, float** buffer, SharpeningParams &sharpenParam);
void deconvsharpeningcam (CieImage* ncie, float** buffer);
void MLsharpen (LabImage* lab);// Manuel's clarity / sharpening
void MLmicrocontrast(LabImage* lab ); //Manuel's microcontrast
diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc
index f9d0ddb3a..ba369333a 100644
--- a/rtengine/ipsharpen.cc
+++ b/rtengine/ipsharpen.cc
@@ -22,12 +22,7 @@
#include "bilateral2.h"
#include "rt_math.h"
#include "sleef.c"
-#ifdef __SSE2__
-#include "sleefsseavx.c"
-#endif
-#ifdef _OPENMP
-#include
-#endif
+#include "opthelper.h"
using namespace std;
@@ -40,11 +35,7 @@ namespace rtengine {
extern const Settings* settings;
-#if defined( __SSE__ ) && defined( WIN32 )
-__attribute__((force_align_arg_pointer)) void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, int H) {
-#else
-void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, int H) {
-#endif
+SSEFUNCTION void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, int H) {
const float dampingFac=-2.0/(damping*damping);
@@ -114,8 +105,8 @@ void ImProcFunctions::dcdamping (float** aI, float** aO, float damping, int W, i
#endif
}
-void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2) {
- if (params->sharpening.enabled==false || params->sharpening.deconvamount<1)
+void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2, SharpeningParams &sharpenParam) {
+ if (sharpenParam.enabled==false || sharpenParam.deconvamount<1)
return;
int W = lab->W, H = lab->H;
@@ -135,13 +126,13 @@ void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2) {
{
AlignedBufferMP buffer(max(W,H));
- float damping = params->sharpening.deconvdamping / 5.0;
- bool needdamp = params->sharpening.deconvdamping > 0;
- for (int k=0; ksharpening.deconviter; k++) {
+ float damping = sharpenParam.deconvdamping / 5.0;
+ bool needdamp = sharpenParam.deconvdamping > 0;
+ for (int k=0; k (tmpI, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
- gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
+ gaussHorizontal (tmpI, tmp, buffer, W, H, sharpenParam.deconvradius / scale);
+ gaussVertical (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale);
if (!needdamp) {
#ifdef _OPENMP
@@ -155,8 +146,8 @@ void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2) {
else
dcdamping (tmp, lab->L, damping, W, H);
- gaussHorizontal (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
- gaussVertical (tmp, tmp, buffer, W, H, params->sharpening.deconvradius / scale);
+ gaussHorizontal (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale);
+ gaussVertical (tmp, tmp, buffer, W, H, sharpenParam.deconvradius / scale);
#ifdef _OPENMP
#pragma omp for
@@ -166,7 +157,7 @@ void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2) {
tmpI[i][j] = tmpI[i][j] * tmp[i][j];
} // end for
- float p2 = params->sharpening.deconvamount / 100.0;
+ float p2 = sharpenParam.deconvamount / 100.0;
float p1 = 1.0 - p2;
#ifdef _OPENMP
@@ -183,101 +174,109 @@ void ImProcFunctions::deconvsharpening (LabImage* lab, float** b2) {
delete [] tmpI;
}
-void ImProcFunctions::sharpening (LabImage* lab, float** b2) {
+void ImProcFunctions::sharpening (LabImage* lab, float** b2, SharpeningParams &sharpenParam) {
- if (params->sharpening.method=="rld") {
- deconvsharpening (lab, b2);
+ if (sharpenParam.method=="rld") {
+ deconvsharpening (lab, b2, sharpenParam);
return;
}
// Rest is UNSHARP MASK
- if (params->sharpening.enabled==false || params->sharpening.amount<1 || lab->W<8 || lab->H<8)
+ if (sharpenParam.enabled==false || sharpenParam.amount<1 || lab->W<8 || lab->H<8)
return;
int W = lab->W, H = lab->H;
float** b3 = NULL;
float** labCopy = NULL;
- if (params->sharpening.edgesonly) {
+ if (sharpenParam.edgesonly) {
b3 = new float*[H];
for (int i=0; isharpening.halocontrol && !params->sharpening.edgesonly) {
+ if (sharpenParam.halocontrol && !sharpenParam.edgesonly) {
// We only need the lab parameter copy in this special case
labCopy = new float*[H];
for( int i=0; i buffer(max(W,H));
- if (params->sharpening.edgesonly==false) {
+ if (sharpenParam.edgesonly==false) {
- gaussHorizontal (lab->L, b2, buffer, W, H, params->sharpening.radius / scale);
- gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale);
+ gaussHorizontal (lab->L, b2, buffer, W, H, sharpenParam.radius / scale);
+ gaussVertical (b2, b2, buffer, W, H, sharpenParam.radius / scale);
}
else {
- bilateral (lab->L, (float**)b3, b2, W, H, params->sharpening.edges_radius / scale, params->sharpening.edges_tolerance, multiThread);
- gaussHorizontal (b3, b2, buffer, W, H, params->sharpening.radius / scale);
- gaussVertical (b2, b2, buffer, W, H, params->sharpening.radius / scale);
+ bilateral (lab->L, (float**)b3, b2, W, H, sharpenParam.edges_radius / scale, sharpenParam.edges_tolerance, multiThread);
+ gaussHorizontal (b3, b2, buffer, W, H, sharpenParam.radius / scale);
+ gaussVertical (b2, b2, buffer, W, H, sharpenParam.radius / scale);
}
float** base = lab->L;
- if (params->sharpening.edgesonly)
+ if (sharpenParam.edgesonly)
base = b3;
- if (params->sharpening.halocontrol==false) {
- #pragma omp for
+ if (sharpenParam.halocontrol==false) {
+#ifdef _OPENMP
+#pragma omp for
+#endif
for (int i=0; isharpening.threshold.multiply(
+ float delta = sharpenParam.threshold.multiply(
min(ABS(diff), upperBound), // X axis value = absolute value of the difference, truncated to the max value of this field
- params->sharpening.amount * diff * 0.01f // Y axis max value
+ sharpenParam.amount * diff * 0.01f // Y axis max value
);
lab->L[i][j] = lab->L[i][j] + delta;
}
}
else {
- if (!params->sharpening.edgesonly) {
+ if (!sharpenParam.edgesonly) {
// make a deep copy of lab->L
+#ifdef _OPENMP
#pragma omp for
+#endif
for( int i=0; iL[i][j];
base = labCopy;
}
- sharpenHaloCtrl (lab, b2, base, W, H);
+ sharpenHaloCtrl (lab, b2, base, W, H, sharpenParam);
}
} // end parallel
- if (params->sharpening.halocontrol && !params->sharpening.edgesonly) {
+ if (sharpenParam.halocontrol && !sharpenParam.edgesonly) {
// delete the deep copy
for( int i=0; isharpening.edgesonly) {
+ if (sharpenParam.edgesonly) {
for (int i=0; isharpening.halocontrol_amount) * 0.01f;
- float sharpFac = params->sharpening.amount * 0.01f;
+ float scale = (100.f - sharpenParam.halocontrol_amount) * 0.01f;
+ float sharpFac = sharpenParam.amount * 0.01f;
float** nL = base;
+#ifdef _OPENMP
#pragma omp for
+#endif
for (int i=2; isharpening.threshold.multiply(
+ float delta = sharpenParam.threshold.multiply(
min(ABS(diff), upperBound), // X axis value = absolute value of the difference
sharpFac * diff // Y axis max value = sharpening.amount * signed difference
);
@@ -368,15 +367,19 @@ void ImProcFunctions::MLsharpen (LabImage* lab) {
for (p=0; pL[ii][kk]/327.68f; // adjust to RT and to 0..100
else if (c==1) L[offset] = lab->a[ii][kk]/327.68f;
- else if (c==2) L[offset] = lab->b[ii][kk]/327.68f;
+ else /*if (c==2) */ L[offset] = lab->b[ii][kk]/327.68f;
}
+#ifdef _OPENMP
#pragma omp parallel for private(j,i,iii,kkk, templab,offset,wH,wV,wD1,wD2,s,lumH,lumV,lumD1,lumD2,v,contrast,f1,f2,f3,f4,difT,difB,difL,difR,difLT,difLB,difRT,difRB) shared(lab,L,amount)
+#endif
for(j=2; jL[ii][kk]/327.68f;
else if (c==1) lumH=lumV=lumD1=lumD2=v=lab->a[ii][kk]/327.68f;
- else if (c==2) lumH=lumV=lumD1=lumD2=v=lab->b[ii][kk]/327.68f;
+ else /* if (c==2) */ lumH=lumV=lumD1=lumD2=v=lab->b[ii][kk]/327.68f;
// contrast detection
@@ -557,13 +560,17 @@ void ImProcFunctions::MLmicrocontrast(LabImage* lab) {
float chmax=8.0f;
LM = new float[width*height];//allocation for Luminance
+#ifdef _OPENMP
#pragma omp parallel for private(offset, i,j) shared(LM)
+#endif
for(j=0; jL[j][i]/327.68f;// adjust to 0.100 and to RT variables
}
+#ifdef _OPENMP
#pragma omp parallel for private(j,i,offset,s,signs,v,n,row,col,offset2,contrast,temp,temp2,temp3,tempL,temp4) shared(lab,LM,amount,chmax,unif,k,L98,L95,L92,L90,L87,L83,L80,L75,L70,L63,L58,Cont0,Cont1,Cont2,Cont3,Cont4,Cont5)
+#endif
for(j=k; j1.0f)
@@ -755,13 +762,17 @@ void ImProcFunctions::MLmicrocontrastcam(CieImage* ncie) {
float chmax=8.0f;
LM = new float[width*height];//allocation for Luminance
+#ifdef _OPENMP
#pragma omp parallel for private(offset, i,j) shared(LM)
+#endif
for(j=0; jsh_p[j][i]/327.68f;// adjust to 0.100 and to RT variables
}
+#ifdef _OPENMP
#pragma omp parallel for private(j,i,offset,s,signs,v,n,row,col,offset2,contrast,temp,temp2,temp3,tempL,temp4) shared(ncie,LM,amount,chmax,unif,k,L98,L95,L92,L90,L87,L83,L80,L75,L70,L63,L58,Cont0,Cont1,Cont2,Cont3,Cont4,Cont5)
+#endif
for(j=k; j1.0f)
@@ -901,9 +912,6 @@ void ImProcFunctions::MLmicrocontrastcam(CieImage* ncie) {
}
-
-
-
void ImProcFunctions::deconvsharpeningcam (CieImage* ncie, float** b2) {
if (params->sharpening.enabled==false || params->sharpening.deconvamount<1)
@@ -1030,7 +1038,9 @@ void ImProcFunctions::sharpeningcam (CieImage* ncie, float** b2) {
base = b3;
if (params->sharpening.halocontrol==false) {
- #pragma omp for
+#ifdef _OPENMP
+#pragma omp for
+#endif
for (int i=0; isharpening.edgesonly) {
// make a deep copy of lab->L
+#ifdef _OPENMP
#pragma omp for
+#endif
for( int i=0; ish_p[i][j];
@@ -1075,7 +1087,9 @@ void ImProcFunctions::sharpenHaloCtrlcam (CieImage* ncie, float** blurmap, float
float sharpFac = params->sharpening.amount * 0.01f;
float** nL = base;
+#ifdef _OPENMP
#pragma omp for
+#endif
for (int i=2; i.
*/
-#include
-#include
-#include
-#include
+//#include
+#include "procparams.h"
#include "rt_math.h"
#include "safegtk.h"
+#include "safekeyfile.h"
+#include "dcp.h"
#include "../rtgui/multilangmgr.h"
-#include "procparams.h"
#include "../rtgui/version.h"
#include "../rtgui/ppversion.h"
-#include "../rtgui/mydiagonalcurve.h"
-#include "../rtgui/myflatcurve.h"
-#include "safekeyfile.h"
-#include "rawimage.h"
-#include "../rtgui/ppversion.h"
#include "../rtgui/paramsedited.h"
-#include "dcp.h"
#include "../rtgui/options.h"
#include
#define APPVERSION VERSION
@@ -803,6 +796,21 @@ void ProcParams::setDefaults () {
sharpening.deconvdamping = 20;
sharpening.deconvamount = 75;
+ prsharpening.enabled = false;
+ prsharpening.radius = 0.5;
+ prsharpening.amount = 200;
+ prsharpening.threshold.setValues(20, 80, 2000, 1200);
+ prsharpening.edgesonly = false;
+ prsharpening.edges_radius = 1.9;
+ prsharpening.edges_tolerance = 1800;
+ prsharpening.halocontrol = false;
+ prsharpening.halocontrol_amount = 85;
+ prsharpening.method = "usm";
+ prsharpening.deconvradius = 0.5;
+ prsharpening.deconviter = 100;
+ prsharpening.deconvdamping = 0;
+ prsharpening.deconvamount = 100;
+
vibrance.enabled = false;
vibrance.pastels = 0;
vibrance.saturated = 0;
@@ -1574,6 +1582,25 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
if (!pedited || pedited->resize.width) keyFile.set_integer ("Resize", "Width", resize.width);
if (!pedited || pedited->resize.height) keyFile.set_integer ("Resize", "Height", resize.height);
+ if (!pedited || pedited->prsharpening.enabled) keyFile.set_boolean ("PostResizeSharpening", "Enabled", prsharpening.enabled);
+ if (!pedited || pedited->prsharpening.method) keyFile.set_string ("PostResizeSharpening", "Method", prsharpening.method);
+ if (!pedited || pedited->prsharpening.radius) keyFile.set_double ("PostResizeSharpening", "Radius", prsharpening.radius);
+ if (!pedited || pedited->prsharpening.amount) keyFile.set_integer ("PostResizeSharpening", "Amount", prsharpening.amount);
+ if (!pedited || pedited->prsharpening.threshold) {
+ Glib::ArrayHandle thresh (prsharpening.threshold.value, 4, Glib::OWNERSHIP_NONE);
+ keyFile.set_integer_list("PostResizeSharpening", "Threshold", thresh);
+ }
+ if (!pedited || pedited->prsharpening.edgesonly) keyFile.set_boolean ("PostResizeSharpening", "OnlyEdges", prsharpening.edgesonly);
+ if (!pedited || pedited->prsharpening.edges_radius) keyFile.set_double ("PostResizeSharpening", "EdgedetectionRadius", prsharpening.edges_radius);
+ if (!pedited || pedited->prsharpening.edges_tolerance) keyFile.set_integer ("PostResizeSharpening", "EdgeTolerance", prsharpening.edges_tolerance);
+ if (!pedited || pedited->prsharpening.halocontrol) keyFile.set_boolean ("PostResizeSharpening", "HalocontrolEnabled", prsharpening.halocontrol);
+ if (!pedited || pedited->prsharpening.halocontrol_amount) keyFile.set_integer ("PostResizeSharpening", "HalocontrolAmount", prsharpening.halocontrol_amount);
+ if (!pedited || pedited->prsharpening.deconvradius) keyFile.set_double ("PostResizeSharpening", "DeconvRadius", prsharpening.deconvradius);
+ if (!pedited || pedited->prsharpening.deconvamount) keyFile.set_integer ("PostResizeSharpening", "DeconvAmount", prsharpening.deconvamount);
+ if (!pedited || pedited->prsharpening.deconvdamping) keyFile.set_integer ("PostResizeSharpening", "DeconvDamping", prsharpening.deconvdamping);
+ if (!pedited || pedited->prsharpening.deconviter) keyFile.set_integer ("PostResizeSharpening", "DeconvIterations", prsharpening.deconviter);
+
+
// save color management settings
if (!pedited || pedited->icm.input) keyFile.set_string ("Color Management", "InputProfile", relativePathIfInside(fname, fnameAbsolute, icm.input));
if (!pedited || pedited->icm.toneCurve) keyFile.set_boolean ("Color Management", "ToneCurve", icm.toneCurve);
@@ -2433,6 +2460,34 @@ if (keyFile.has_group ("Resize")) {
if (keyFile.has_key ("Resize", "Height")) { resize.height = keyFile.get_integer ("Resize", "Height"); if (pedited) pedited->resize.height = true; }
}
+ // load post resize sharpening
+if (keyFile.has_group ("PostResizeSharpening")) {
+ if (keyFile.has_key ("PostResizeSharpening", "Enabled")) { prsharpening.enabled = keyFile.get_boolean ("PostResizeSharpening", "Enabled"); if (pedited) pedited->prsharpening.enabled = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "Radius")) { prsharpening.radius = keyFile.get_double ("PostResizeSharpening", "Radius"); if (pedited) pedited->prsharpening.radius = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "Amount")) { prsharpening.amount = keyFile.get_integer ("PostResizeSharpening", "Amount"); if (pedited) pedited->prsharpening.amount = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "Threshold")) {
+ if (ppVersion < 302) {
+ int thresh = min(keyFile.get_integer ("PostResizeSharpening", "Threshold"), 2000);
+ prsharpening.threshold.setValues(thresh, thresh, 2000, 2000); // TODO: 2000 is the maximum value and is taken of rtgui/sharpening.cc ; should be changed by the tool modularization
+ }
+ else {
+ Glib::ArrayHandle thresh = keyFile.get_integer_list ("PostResizeSharpening", "Threshold");
+ prsharpening.threshold.setValues(thresh.data()[0], thresh.data()[1], min(thresh.data()[2], 2000), min(thresh.data()[3], 2000));
+ }
+ if (pedited) pedited->prsharpening.threshold = true;
+ }
+ if (keyFile.has_key ("PostResizeSharpening", "OnlyEdges")) { prsharpening.edgesonly = keyFile.get_boolean ("PostResizeSharpening", "OnlyEdges"); if (pedited) pedited->prsharpening.edgesonly = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "EdgedetectionRadius")) { prsharpening.edges_radius = keyFile.get_double ("PostResizeSharpening", "EdgedetectionRadius"); if (pedited) pedited->prsharpening.edges_radius = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "EdgeTolerance")) { prsharpening.edges_tolerance = keyFile.get_integer ("PostResizeSharpening", "EdgeTolerance"); if (pedited) pedited->prsharpening.edges_tolerance = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "HalocontrolEnabled")) { prsharpening.halocontrol = keyFile.get_boolean ("PostResizeSharpening", "HalocontrolEnabled"); if (pedited) pedited->prsharpening.halocontrol = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "HalocontrolAmount")) { prsharpening.halocontrol_amount = keyFile.get_integer ("PostResizeSharpening", "HalocontrolAmount"); if (pedited) pedited->prsharpening.halocontrol_amount = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "Method")) { prsharpening.method = keyFile.get_string ("PostResizeSharpening", "Method"); if (pedited) pedited->prsharpening.method = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "DeconvRadius")) { prsharpening.deconvradius = keyFile.get_double ("PostResizeSharpening", "DeconvRadius"); if (pedited) pedited->prsharpening.deconvradius = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "DeconvAmount")) { prsharpening.deconvamount = keyFile.get_integer ("PostResizeSharpening", "DeconvAmount"); if (pedited) pedited->prsharpening.deconvamount = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "DeconvDamping")) { prsharpening.deconvdamping = keyFile.get_integer ("PostResizeSharpening", "DeconvDamping"); if (pedited) pedited->prsharpening.deconvdamping = true; }
+ if (keyFile.has_key ("PostResizeSharpening", "DeconvIterations")) { prsharpening.deconviter = keyFile.get_integer ("PostResizeSharpening", "DeconvIterations"); if (pedited) pedited->prsharpening.deconviter = true; }
+}
+
// load color management settings
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; }
@@ -2899,6 +2954,20 @@ bool ProcParams::operator== (const ProcParams& other) {
&& sharpening.deconvradius == other.sharpening.deconvradius
&& sharpening.deconviter == other.sharpening.deconviter
&& sharpening.deconvdamping == other.sharpening.deconvdamping
+ && prsharpening.enabled == other.prsharpening.enabled
+ && prsharpening.radius == other.prsharpening.radius
+ && prsharpening.amount == other.prsharpening.amount
+ && prsharpening.threshold == other.prsharpening.threshold
+ && prsharpening.edgesonly == other.prsharpening.edgesonly
+ && prsharpening.edges_radius == other.prsharpening.edges_radius
+ && prsharpening.edges_tolerance == other.prsharpening.edges_tolerance
+ && prsharpening.halocontrol == other.prsharpening.halocontrol
+ && prsharpening.halocontrol_amount== other.prsharpening.halocontrol_amount
+ && prsharpening.method == other.prsharpening.method
+ && prsharpening.deconvamount == other.prsharpening.deconvamount
+ && prsharpening.deconvradius == other.prsharpening.deconvradius
+ && prsharpening.deconviter == other.prsharpening.deconviter
+ && prsharpening.deconvdamping == other.prsharpening.deconvdamping
&& vibrance.enabled == other.vibrance.enabled
&& vibrance.pastels == other.vibrance.pastels
&& vibrance.saturated == other.vibrance.saturated
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index b328215d7..1cfd82ffc 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -21,7 +21,6 @@
#include
#include
-#include
#include
#include
#include "LUT.h"
@@ -1085,6 +1084,7 @@ class ProcParams {
RGBCurvesParams rgbCurves; ///< RGB curves parameters
ColorToningParams colorToning; ///< Color Toning parameters
SharpeningParams sharpening; ///< Sharpening parameters
+ SharpeningParams prsharpening; ///< Sharpening parameters for post resize sharpening
SharpenEdgeParams sharpenEdge; ///< Sharpen edge parameters
SharpenMicroParams sharpenMicro; ///< Sharpen microcontrast parameters
VibranceParams vibrance; ///< Vibrance parameters
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index cadb91064..9a77c8d58 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -391,6 +391,21 @@ DIRPYREQUALIZER, //EvWavgamma
DIRPYREQUALIZER, //EvWavCLCurve
DIRPYREQUALIZER, //EvWavopacity
DIRPYREQUALIZER, //EvWavBAmet
-DIRPYREQUALIZER //EvWavopacityWL
+DIRPYREQUALIZER, //EvWavopacityWL
+RESIZE, // EvPrShrEnabled
+RESIZE, // EvPrShrRadius
+RESIZE, // EvPrShrAmount
+RESIZE, // EvPrShrThresh
+RESIZE, // EvPrShrEdgeOnly
+RESIZE, // EvPrShrEdgeRadius=375,
+RESIZE, // EvPrShrEdgeTolerance=376,
+RESIZE, // EvPrShrHaloControl=377,
+RESIZE, // EvPrShrHaloAmount=378,
+RESIZE, // EvPrShrMethod=379,
+RESIZE, // EvPrShrDRadius=380,
+RESIZE, // EvPrShrDAmount=381,
+RESIZE, // EvPrShrDDamping=382,
+RESIZE // EvPrShrDIterations=383,
+
};
diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h
index ba914e77d..17b96302c 100644
--- a/rtengine/refreshmap.h
+++ b/rtengine/refreshmap.h
@@ -19,11 +19,9 @@
#ifndef __REFRESHMAP__
#define __REFRESHMAP__
-#include
-
-// Use M_VOID is you wish to update the proc params without updating the preview at all !
+// Use M_VOID if you wish to update the proc params without updating the preview at all !
#define M_VOID (1<<15)
-// Use M_MINUPDATE if you you wish to update the preview without modifying the image (think about it like a "refreshPreview")
+// Use M_MINUPDATE if you wish to update the preview without modifying the image (think about it like a "refreshPreview")
// Must NOT be used with other event (i.e. will be used for MINUPDATE only)
#define M_MINUPDATE (1<<14)
// Force high quality
diff --git a/rtengine/simpleprocess.cc b/rtengine/simpleprocess.cc
index 73a3d5643..e4a54d0fb 100644
--- a/rtengine/simpleprocess.cc
+++ b/rtengine/simpleprocess.cc
@@ -26,15 +26,10 @@
#include "processingjob.h"
#include
#include "../rtgui/options.h"
-#include
#include "rawimagesource.h"
-#include "../rtgui/ppversion.h"
#include "../rtgui/multilangmgr.h"
#include "mytime.h"
#undef THREAD_PRIORITY_NORMAL
-#ifdef _OPENMP
-#include
-#endif
namespace rtengine {
extern const Settings* settings;
@@ -764,7 +759,7 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
for (int i=0; iW;
ch = labView->H;
+ if(params.prsharpening.enabled) {
+ float **buffer = new float*[ch];
+ for (int i=0; istate & GDK_CONTROL_MASK;
- bool shift = event->state & GDK_SHIFT_MASK;
if (!ctrl) {
switch(event->keyval) {
diff --git a/rtgui/main.cc b/rtgui/main.cc
index 8e536d663..b8daf5af5 100644
--- a/rtgui/main.cc
+++ b/rtgui/main.cc
@@ -22,12 +22,12 @@
// newer (non customized) versions of this file go to raw.cc_new
// This file is for your program, I won't touch it again!
-
-#ifdef __GNUC__
- #if defined(__FAST_MATH__)
- #error Using the -ffast-math CFLAG is known to lead to problems. Disable it to compile RawTherapee.
- #endif
-#endif
+
+#ifdef __GNUC__
+ #if defined(__FAST_MATH__)
+ #error Using the -ffast-math CFLAG is known to lead to problems. Disable it to compile RawTherapee.
+ #endif
+#endif
#include "config.h"
#include
@@ -320,7 +320,6 @@ int processLineParams( int argc, char **argv )
std::vector inputFiles;
Glib::ustring outputPath = "";
std::vector processingParams;
- bool isDirectory=false;
bool outputDirectory=false;
bool overwriteFiles=false;
bool sideProcParams=false;
@@ -429,7 +428,6 @@ int processLineParams( int argc, char **argv )
continue;
}
if( safe_file_test( safe_filename_to_utf8(argv[iArg]), Glib::FILE_TEST_IS_DIR )){
- isDirectory = true;
std::vector names;
Glib::RefPtr dir = Gio::File::create_for_path ( argv[iArg] );
safe_build_file_list (dir, names, argv[iArg] );
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 3037da47b..13832399a 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -107,6 +107,20 @@ void ParamsEdited::set (bool v) {
sharpening.deconvradius = v;
sharpening.deconviter = v;
sharpening.deconvdamping = v;
+ prsharpening.enabled = v;
+ prsharpening.radius = v;
+ prsharpening.amount = v;
+ prsharpening.threshold = v;
+ prsharpening.edgesonly = v;
+ prsharpening.edges_radius = v;
+ prsharpening.edges_tolerance = v;
+ prsharpening.halocontrol = v;
+ prsharpening.halocontrol_amount = v;
+ prsharpening.method = v;
+ prsharpening.deconvamount = v;
+ prsharpening.deconvradius = v;
+ prsharpening.deconviter = v;
+ prsharpening.deconvdamping = v;
sharpenEdge.enabled = v;
sharpenEdge.passes = v;
sharpenEdge.amount = v;
@@ -523,6 +537,20 @@ void ParamsEdited::initFrom (const std::vector
sharpening.deconvradius = sharpening.deconvradius && p.sharpening.deconvradius == other.sharpening.deconvradius;
sharpening.deconviter = sharpening.deconviter && p.sharpening.deconviter == other.sharpening.deconviter;
sharpening.deconvdamping = sharpening.deconvdamping && p.sharpening.deconvdamping == other.sharpening.deconvdamping;
+ prsharpening.enabled = prsharpening.enabled && p.prsharpening.enabled == other.prsharpening.enabled;
+ prsharpening.radius = prsharpening.radius && p.prsharpening.radius == other.prsharpening.radius;
+ prsharpening.amount = prsharpening.amount && p.prsharpening.amount == other.prsharpening.amount;
+ prsharpening.threshold = prsharpening.threshold && p.prsharpening.threshold == other.prsharpening.threshold;
+ prsharpening.edgesonly = prsharpening.edgesonly && p.prsharpening.edgesonly == other.prsharpening.edgesonly;
+ prsharpening.edges_radius = prsharpening.edges_radius && p.prsharpening.edges_radius == other.prsharpening.edges_radius;
+ prsharpening.edges_tolerance = prsharpening.edges_tolerance && p.prsharpening.edges_tolerance == other.prsharpening.edges_tolerance;
+ prsharpening.halocontrol = prsharpening.halocontrol && p.prsharpening.halocontrol == other.prsharpening.halocontrol;
+ prsharpening.halocontrol_amount = prsharpening.halocontrol_amount && p.prsharpening.halocontrol_amount == other.prsharpening.halocontrol_amount;
+ prsharpening.method = prsharpening.method && p.prsharpening.method == other.prsharpening.method;
+ prsharpening.deconvamount = prsharpening.deconvamount && p.prsharpening.deconvamount == other.prsharpening.deconvamount;
+ prsharpening.deconvradius = prsharpening.deconvradius && p.prsharpening.deconvradius == other.prsharpening.deconvradius;
+ prsharpening.deconviter = prsharpening.deconviter && p.prsharpening.deconviter == other.prsharpening.deconviter;
+ prsharpening.deconvdamping = prsharpening.deconvdamping && p.prsharpening.deconvdamping == other.prsharpening.deconvdamping;
vibrance.enabled = vibrance.enabled && p.vibrance.enabled == other.vibrance.enabled;
vibrance.pastels = vibrance.pastels && p.vibrance.pastels == other.vibrance.pastels;
vibrance.saturated = vibrance.saturated && p.vibrance.saturated == other.vibrance.saturated;
@@ -931,6 +959,20 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (sharpening.deconvradius) toEdit.sharpening.deconvradius = mods.sharpening.deconvradius;
if (sharpening.deconviter) toEdit.sharpening.deconviter = mods.sharpening.deconviter;
if (sharpening.deconvdamping) toEdit.sharpening.deconvdamping = mods.sharpening.deconvdamping;
+ if (prsharpening.enabled) toEdit.prsharpening.enabled = mods.prsharpening.enabled;
+ if (prsharpening.radius) toEdit.prsharpening.radius = mods.prsharpening.radius;
+ if (prsharpening.amount) toEdit.prsharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.amount + mods.prsharpening.amount : mods.prsharpening.amount;
+ if (prsharpening.threshold) toEdit.prsharpening.threshold = mods.prsharpening.threshold;
+ if (prsharpening.edgesonly) toEdit.prsharpening.edgesonly = mods.prsharpening.edgesonly;
+ if (prsharpening.edges_radius) toEdit.prsharpening.edges_radius = mods.prsharpening.edges_radius;
+ if (prsharpening.edges_tolerance) toEdit.prsharpening.edges_tolerance = mods.prsharpening.edges_tolerance;
+ if (prsharpening.halocontrol) toEdit.prsharpening.halocontrol = mods.prsharpening.halocontrol;
+ if (prsharpening.halocontrol_amount) toEdit.prsharpening.halocontrol_amount = mods.prsharpening.halocontrol_amount;
+ if (prsharpening.method) toEdit.prsharpening.method = mods.prsharpening.method;
+ if (prsharpening.deconvamount) toEdit.prsharpening.deconvamount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.prsharpening.deconvamount + mods.prsharpening.deconvamount : mods.prsharpening.deconvamount;
+ if (prsharpening.deconvradius) toEdit.prsharpening.deconvradius = mods.prsharpening.deconvradius;
+ if (prsharpening.deconviter) toEdit.prsharpening.deconviter = mods.prsharpening.deconviter;
+ if (prsharpening.deconvdamping) toEdit.prsharpening.deconvdamping = mods.prsharpening.deconvdamping;
if (vibrance.enabled) toEdit.vibrance.enabled = mods.vibrance.enabled;
if (vibrance.pastels) toEdit.vibrance.pastels = dontforceSet && options.baBehav[ADDSET_VIBRANCE_PASTELS] ? toEdit.vibrance.pastels + mods.vibrance.pastels : mods.vibrance.pastels;
if (vibrance.saturated) toEdit.vibrance.saturated = dontforceSet && options.baBehav[ADDSET_VIBRANCE_SATURATED] ? toEdit.vibrance.saturated + mods.vibrance.saturated : mods.vibrance.saturated;
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index a2379760d..3298301b1 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -638,6 +638,7 @@ class ParamsEdited {
RGBCurvesParamsEdited rgbCurves;
ColorToningEdited colorToning;
SharpeningParamsEdited sharpening;
+ SharpeningParamsEdited prsharpening;
SharpenEdgeParamsEdited sharpenEdge;
SharpenMicroParamsEdited sharpenMicro;
VibranceParamsEdited vibrance;
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index ef2e57ae6..26ba14c35 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -1118,7 +1118,7 @@ Gtk::Widget* Preferences::getFileBrowserPanel () {
vbro->pack_start (*filmStripOverlayedFileNames, Gtk::PACK_SHRINK, 0);
vbro->pack_start (*sameThumbSize, Gtk::PACK_SHRINK, 0);
vbro->pack_start (*ckbInternalThumbIfUntouched, Gtk::PACK_SHRINK, 0);
-
+
Gtk::HBox* hbrecent = Gtk::manage( new Gtk::HBox () );
Gtk::Label* labrecent = Gtk::manage( new Gtk::Label (M("PREFERENCES_MAXRECENTFOLDERS")+":") );
maxRecentFolders = Gtk::manage( new Gtk::SpinButton () );
@@ -1127,7 +1127,7 @@ Gtk::Widget* Preferences::getFileBrowserPanel () {
maxRecentFolders->set_digits (0);
maxRecentFolders->set_increments (1, 5);
maxRecentFolders->set_range (1, 25);
- vbro->pack_start (*hbrecent, Gtk::PACK_SHRINK, 4);
+ vbro->pack_start (*hbrecent, Gtk::PACK_SHRINK, 4);
fro->add (*vbro);
@@ -1423,7 +1423,7 @@ void Preferences::storePreferences () {
moptions.parseExtensions.push_back (c[i][extensionColumns.ext]);
moptions.parseExtensionsEnabled.push_back (c[i][extensionColumns.enabled]);
}
-
+
moptions.maxRecentFolders = (int)maxRecentFolders->get_value();
moptions.maxThumbnailHeight = (int)maxThumbSize->get_value ();
moptions.maxCacheEntries = (int)maxCacheEntries->get_value ();
@@ -1555,7 +1555,7 @@ void Preferences::fillPreferences () {
#ifdef WIN32
edPS->set_active (moptions.editorToSendTo==2);
if (safe_file_test (moptions.gimpDir, Glib::FILE_TEST_IS_DIR))
- gimpDir->set_current_folder (moptions.gimpDir);
+ gimpDir->set_current_folder (moptions.gimpDir);
if (safe_file_test (moptions.psDir, Glib::FILE_TEST_IS_DIR))
psDir->set_current_folder (moptions.psDir);
#elif defined __APPLE__
@@ -1587,7 +1587,7 @@ void Preferences::fillPreferences () {
row[extensionColumns.ext] = moptions.parseExtensions[i];
}
- maxThumbSize->set_value (moptions.maxThumbnailHeight);
+ maxThumbSize->set_value (moptions.maxThumbnailHeight);
maxRecentFolders->set_value(moptions.maxRecentFolders);
maxCacheEntries->set_value (moptions.maxCacheEntries);
overlayedFileNames->set_active (moptions.overlayedFileNames);
@@ -1633,7 +1633,7 @@ void Preferences::fillPreferences () {
for (size_t i=0; ichildren().begin(); sections!=behModel->children().end(); sections++)
for (Gtk::TreeIter adjs=sections->children().begin(); adjs!=sections->children().end(); adjs++)
- if (adjs->get_value (behavColumns.addsetid) == i) {
+ if (adjs->get_value (behavColumns.addsetid) == (int)i) {
adjs->set_value (behavColumns.badd, moptions.baBehav[i]==1);
adjs->set_value (behavColumns.bset, moptions.baBehav[i]!=1);
break;
@@ -2025,7 +2025,7 @@ void Preferences::behAddAllPressed () {
for (size_t i=0; ichildren().begin(); sections!=behModel->children().end(); sections++)
for (Gtk::TreeIter adjs=sections->children().begin(); adjs!=sections->children().end(); adjs++)
- if (adjs->get_value (behavColumns.addsetid) == i) {
+ if (adjs->get_value (behavColumns.addsetid) == (int)i) {
adjs->set_value (behavColumns.badd, true);
adjs->set_value (behavColumns.bset, false);
break;
@@ -2039,7 +2039,7 @@ void Preferences::behSetAllPressed () {
for (size_t i=0; ichildren().begin(); sections!=behModel->children().end(); sections++)
for (Gtk::TreeIter adjs=sections->children().begin(); adjs!=sections->children().end(); adjs++)
- if (adjs->get_value (behavColumns.addsetid) == i) {
+ if (adjs->get_value (behavColumns.addsetid) == (int)i) {
adjs->set_value (behavColumns.badd, false);
adjs->set_value (behavColumns.bset, true);
break;
diff --git a/rtgui/prsharpening.cc b/rtgui/prsharpening.cc
new file mode 100644
index 000000000..1334ce06f
--- /dev/null
+++ b/rtgui/prsharpening.cc
@@ -0,0 +1,483 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2004-2010 Gabor Horvath
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+#include "prsharpening.h"
+#include
+#include "guiutils.h"
+
+using namespace rtengine;
+using namespace rtengine::procparams;
+
+PrSharpening::PrSharpening () : FoldableToolPanel(this, "prsharpening", M("TP_PRSHARPENING_LABEL"), false, true)
+{
+
+ std::vector milestones;
+ milestones.push_back( GradientMilestone(0.0, 0.0, 0.0, 0.0) );
+ milestones.push_back( GradientMilestone(1.0, 1.0, 1.0, 1.0) );
+
+ //setEnabledTooltipMarkup(M("TP_PRSHARPENING_TOOLTIP"));
+
+ Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ());
+ hb->set_border_width (4);
+ hb->show ();
+ Gtk::Label* ml = Gtk::manage (new Gtk::Label (M("TP_SHARPENING_METHOD") + ":"));
+ ml->show ();
+ method = Gtk::manage (new MyComboBoxText ());
+ method->append_text (M("TP_SHARPENING_USM"));
+ method->append_text (M("TP_SHARPENING_RLD"));
+ method->show ();
+ hb->pack_start(*ml, Gtk::PACK_SHRINK, 4);
+ hb->pack_start(*method);
+ pack_start (*hb);
+
+ rld = new Gtk::VBox ();
+ dradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.01, 0.75));
+ damount = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_AMOUNT"), 0.0, 100, 1, 75));
+ ddamping = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_DAMPING"), 0, 100, 1, 20));
+ diter = Gtk::manage (new Adjuster (M("TP_SHARPENING_RLD_ITERATIONS"), 5, 100, 1, 30));
+ rld->pack_start (*dradius);
+ rld->pack_start (*damount);
+ rld->pack_start (*ddamping);
+ rld->pack_start (*diter);
+ dradius->show ();
+ damount->show ();
+ ddamping->show ();
+ diter->show ();
+ rld->show ();
+
+ usm = new Gtk::VBox ();
+ usm->show ();
+
+ Gtk::HSeparator *hsep6a = Gtk::manage (new Gtk::HSeparator());
+ amount = Gtk::manage (new Adjuster (M("TP_SHARPENING_AMOUNT"), 1, 1000, 1, 200));
+ radius = Gtk::manage (new Adjuster (M("TP_SHARPENING_RADIUS"), 0.3, 3, 0.01, 0.5));
+ threshold = Gtk::manage (new ThresholdAdjuster (M("TP_SHARPENING_THRESHOLD"), 0., 2000., 20., 80., 2000., 1200., 0, false));
+ threshold->setAdjusterListener (this);
+ threshold->setBgGradient(milestones);
+ pack_start(*hsep6a, Gtk::PACK_SHRINK, 2);
+
+ pack_start (*usm);
+
+ usm->pack_start(*radius);
+ usm->pack_start(*amount);
+ usm->pack_start(*threshold);
+ hsep6a->show ();
+ radius->show ();
+ amount->show ();
+ threshold->show ();
+
+ Gtk::HSeparator *hsep6 = Gtk::manage (new Gtk::HSeparator());
+ edgesonly = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_ONLYEDGES")));
+ edgesonly->set_active (false);
+ edgebox = new Gtk::VBox ();
+ eradius = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDRADIUS"), 0.5, 2.5, 0.1, 1.9));
+ etolerance = Gtk::manage (new Adjuster (M("TP_SHARPENING_EDTOLERANCE"), 10, 10000, 100, 1000));
+ usm->pack_start(*hsep6, Gtk::PACK_SHRINK, 2);
+ usm->pack_start(*edgesonly);
+ edgebox->pack_start(*eradius);
+ edgebox->pack_start(*etolerance);
+ edgebox->show ();
+ edgebin = Gtk::manage (new Gtk::VBox ());
+ usm->pack_start (*edgebin);
+ edgebin->show ();
+ hsep6->show();
+ edgesonly->show();
+ eradius->show();
+ etolerance->show();
+
+ Gtk::HSeparator *hsep6b = Gtk::manage (new Gtk::HSeparator());
+ halocontrol = Gtk::manage (new Gtk::CheckButton (M("TP_SHARPENING_HALOCONTROL")));
+ halocontrol->set_active (false);
+ hcbox = new Gtk::VBox ();
+ hcamount = Gtk::manage (new Adjuster (M("TP_SHARPENING_HCAMOUNT"), 1, 100, 1, 75));
+ usm->pack_start(*hsep6b, Gtk::PACK_SHRINK, 2);
+ usm->pack_start(*halocontrol);
+ hcbox->pack_start(*hcamount);
+ hcbox->show ();
+ hcbin = Gtk::manage (new Gtk::VBox ());
+ usm->pack_start (*hcbin);
+ hcbin->show ();
+ hsep6b->show ();
+ halocontrol->show ();
+ hcamount->show ();
+
+ dradius->setAdjusterListener (this);
+ damount->setAdjusterListener (this);
+ ddamping->setAdjusterListener (this);
+ diter->setAdjusterListener (this);
+ radius->setAdjusterListener (this);
+ amount->setAdjusterListener (this);
+ eradius->setAdjusterListener (this);
+ etolerance->setAdjusterListener (this);
+ hcamount->setAdjusterListener (this);
+
+ edgebox->reference ();
+ hcbox->reference ();
+ usm->reference ();
+ rld->reference ();
+
+ eonlyConn = edgesonly->signal_toggled().connect( sigc::mem_fun(*this, &PrSharpening::edgesonly_toggled) );
+ hcConn = halocontrol->signal_toggled().connect( sigc::mem_fun(*this, &PrSharpening::halocontrol_toggled) );
+ method->signal_changed().connect( sigc::mem_fun(*this, &PrSharpening::method_changed) );
+}
+
+PrSharpening::~PrSharpening ()
+{
+
+ delete usm;
+ delete rld;
+ delete edgebox;
+ delete hcbox;
+}
+
+
+void PrSharpening::read (const ProcParams* pp, const ParamsEdited* pedited)
+{
+
+ disableListener ();
+
+ if (pedited) {
+ amount->setEditedState (pedited->prsharpening.amount ? Edited : UnEdited);
+ radius->setEditedState (pedited->prsharpening.radius ? Edited : UnEdited);
+ threshold->setEditedState (pedited->prsharpening.threshold ? Edited : UnEdited);
+ eradius->setEditedState (pedited->prsharpening.edges_radius ? Edited : UnEdited);
+ etolerance->setEditedState (pedited->prsharpening.edges_tolerance ? Edited : UnEdited);
+ hcamount->setEditedState (pedited->prsharpening.halocontrol_amount ? Edited : UnEdited);
+ damount->setEditedState (pedited->prsharpening.deconvamount ? Edited : UnEdited);
+ dradius->setEditedState (pedited->prsharpening.deconvradius ? Edited : UnEdited);
+ diter->setEditedState (pedited->prsharpening.deconviter ? Edited : UnEdited);
+ ddamping->setEditedState (pedited->prsharpening.deconvdamping ? Edited : UnEdited);
+
+ halocontrol->set_inconsistent (multiImage && !pedited->prsharpening.halocontrol);
+ edgesonly->set_inconsistent (multiImage && !pedited->prsharpening.edgesonly);
+ set_inconsistent (multiImage && !pedited->prsharpening.enabled);
+ }
+
+ setEnabled (pp->prsharpening.enabled);
+
+ eonlyConn.block (true);
+ edgesonly->set_active (pp->prsharpening.edgesonly);
+ eonlyConn.block (false);
+ lastEdgesOnly = pp->prsharpening.edgesonly;
+
+ hcConn.block (true);
+ halocontrol->set_active (pp->prsharpening.halocontrol);
+ hcConn.block (false);
+ lastHaloControl = pp->prsharpening.halocontrol;
+
+ amount->setValue (pp->prsharpening.amount);
+ radius->setValue (pp->prsharpening.radius);
+ threshold->setValue(pp->prsharpening.threshold);
+ eradius->setValue (pp->prsharpening.edges_radius);
+ etolerance->setValue (pp->prsharpening.edges_tolerance);
+ hcamount->setValue (pp->prsharpening.halocontrol_amount);
+
+ dradius->setValue (pp->prsharpening.deconvradius);
+ damount->setValue (pp->prsharpening.deconvamount);
+ diter->setValue (pp->prsharpening.deconviter);
+ ddamping->setValue (pp->prsharpening.deconvdamping);
+
+ if (!batchMode) {
+ removeIfThere (edgebin, edgebox, false);
+
+ if (edgesonly->get_active ()) {
+ edgebin->pack_start (*edgebox);
+ }
+
+ removeIfThere (hcbin, hcbox, false);
+
+ if (halocontrol->get_active ()) {
+ hcbin->pack_start (*hcbox);
+ }
+
+ }
+
+ if (pedited && !pedited->prsharpening.method) {
+ method->set_active (2);
+ } else if (pp->prsharpening.method == "usm") {
+ method->set_active (0);
+ } else if (pp->prsharpening.method == "rld") {
+ method->set_active (1);
+ }
+
+ enableListener ();
+}
+
+void PrSharpening::write (ProcParams* pp, ParamsEdited* pedited)
+{
+
+ pp->prsharpening.amount = (int)amount->getValue();
+ pp->prsharpening.enabled = getEnabled ();
+ pp->prsharpening.radius = radius->getValue ();
+ pp->prsharpening.threshold = threshold->getValue ();
+ pp->prsharpening.edgesonly = edgesonly->get_active ();
+ pp->prsharpening.edges_radius = eradius->getValue ();
+ pp->prsharpening.edges_tolerance = (int)etolerance->getValue ();
+ pp->prsharpening.halocontrol = halocontrol->get_active ();
+ pp->prsharpening.halocontrol_amount = (int)hcamount->getValue ();
+ pp->prsharpening.deconvradius = dradius->getValue ();
+ pp->prsharpening.deconviter = (int)diter->getValue ();
+ pp->prsharpening.deconvamount = (int)damount->getValue ();
+ pp->prsharpening.deconvdamping = (int)ddamping->getValue ();
+
+ if (method->get_active_row_number() == 0) {
+ pp->prsharpening.method = "usm";
+ } else if (method->get_active_row_number() == 1) {
+ pp->prsharpening.method = "rld";
+ }
+
+ if (pedited) {
+ pedited->prsharpening.amount = amount->getEditedState ();
+ pedited->prsharpening.radius = radius->getEditedState ();
+ pedited->prsharpening.threshold = threshold->getEditedState ();
+ pedited->prsharpening.edges_radius = eradius->getEditedState ();
+ pedited->prsharpening.edges_tolerance = etolerance->getEditedState ();
+ pedited->prsharpening.halocontrol_amount = hcamount->getEditedState ();
+ pedited->prsharpening.deconvamount = damount->getEditedState ();
+ pedited->prsharpening.deconvradius = dradius->getEditedState ();
+ pedited->prsharpening.deconviter = diter->getEditedState ();
+ pedited->prsharpening.deconvdamping = ddamping->getEditedState ();
+ pedited->prsharpening.method = method->get_active_row_number() != 2;
+ pedited->prsharpening.halocontrol = !halocontrol->get_inconsistent();
+ pedited->prsharpening.edgesonly = !edgesonly->get_inconsistent();
+ pedited->prsharpening.enabled = !get_inconsistent();
+ }
+}
+
+void PrSharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited)
+{
+
+ amount->setDefault (defParams->prsharpening.amount);
+ radius->setDefault (defParams->prsharpening.radius);
+ threshold->setDefault (defParams->prsharpening.threshold);
+ eradius->setDefault (defParams->prsharpening.edges_radius);
+ etolerance->setDefault (defParams->prsharpening.edges_tolerance);
+ hcamount->setDefault (defParams->prsharpening.halocontrol_amount);
+ damount->setDefault (defParams->prsharpening.deconvamount);
+ dradius->setDefault (defParams->prsharpening.deconvradius);
+ diter->setDefault (defParams->prsharpening.deconviter);
+ ddamping->setDefault (defParams->prsharpening.deconvdamping);
+
+ if (pedited) {
+ amount->setDefaultEditedState (pedited->prsharpening.amount ? Edited : UnEdited);
+ radius->setDefaultEditedState (pedited->prsharpening.radius ? Edited : UnEdited);
+ threshold->setDefaultEditedState (pedited->prsharpening.threshold ? Edited : UnEdited);
+ eradius->setDefaultEditedState (pedited->prsharpening.edges_radius ? Edited : UnEdited);
+ etolerance->setDefaultEditedState (pedited->prsharpening.edges_tolerance ? Edited : UnEdited);
+ hcamount->setDefaultEditedState (pedited->prsharpening.halocontrol_amount ? Edited : UnEdited);
+ damount->setDefaultEditedState (pedited->prsharpening.deconvamount ? Edited : UnEdited);
+ dradius->setDefaultEditedState (pedited->prsharpening.deconvradius ? Edited : UnEdited);
+ diter->setDefaultEditedState (pedited->prsharpening.deconviter ? Edited : UnEdited);
+ ddamping->setDefaultEditedState (pedited->prsharpening.deconvdamping ? Edited : UnEdited);
+ } else {
+ amount->setDefaultEditedState (Irrelevant);
+ radius->setDefaultEditedState (Irrelevant);
+ threshold->setDefaultEditedState (Irrelevant);
+ eradius->setDefaultEditedState (Irrelevant);
+ etolerance->setDefaultEditedState (Irrelevant);
+ hcamount->setDefaultEditedState (Irrelevant);
+ damount->setDefaultEditedState (Irrelevant);
+ dradius->setDefaultEditedState (Irrelevant);
+ diter->setDefaultEditedState (Irrelevant);
+ ddamping->setDefaultEditedState (Irrelevant);
+ }
+}
+
+void PrSharpening::adjusterChanged (Adjuster* a, double newval)
+{
+
+ if (listener && (multiImage || getEnabled()) ) {
+
+ Glib::ustring costr;
+
+ if (a == radius || a == dradius) {
+ costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue());
+ } else if (a == eradius) {
+ costr = Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue());
+ } else {
+ costr = Glib::ustring::format ((int)a->getValue());
+ }
+
+ if (a == amount) {
+ listener->panelChanged (EvPrShrAmount, costr);
+ } else if (a == radius) {
+ listener->panelChanged (EvPrShrRadius, costr);
+ } else if (a == eradius) {
+ listener->panelChanged (EvPrShrEdgeRadius, costr);
+ } else if (a == etolerance) {
+ listener->panelChanged (EvPrShrEdgeTolerance, costr);
+ } else if (a == hcamount) {
+ listener->panelChanged (EvPrShrHaloAmount, costr);
+ } else if (a == dradius) {
+ listener->panelChanged (EvPrShrDRadius, costr);
+ } else if (a == damount) {
+ listener->panelChanged (EvPrShrDAmount, costr);
+ } else if (a == ddamping) {
+ listener->panelChanged (EvPrShrDDamping, costr);
+ } else if (a == diter) {
+ listener->panelChanged (EvPrShrDIterations, costr);
+ }
+ }
+}
+
+void PrSharpening::enabledChanged ()
+{
+
+ if (listener) {
+ if (get_inconsistent()) {
+ listener->panelChanged (EvPrShrEnabled, M("GENERAL_UNCHANGED"));
+ } else if (getEnabled()) {
+ listener->panelChanged (EvPrShrEnabled, M("GENERAL_ENABLED"));
+ } else {
+ listener->panelChanged (EvPrShrEnabled, M("GENERAL_DISABLED"));
+ }
+ }
+}
+
+void PrSharpening::edgesonly_toggled ()
+{
+
+ if (multiImage) {
+ if (edgesonly->get_inconsistent()) {
+ edgesonly->set_inconsistent (false);
+ eonlyConn.block (true);
+ edgesonly->set_active (false);
+ eonlyConn.block (false);
+ } else if (lastEdgesOnly) {
+ edgesonly->set_inconsistent (true);
+ }
+
+ lastEdgesOnly = edgesonly->get_active ();
+ }
+
+ if (!batchMode) {
+ removeIfThere (edgebin, edgebox, false);
+
+ if (edgesonly->get_active ()) {
+ edgebin->pack_start (*edgebox);
+ }
+ }
+
+ if (listener && (multiImage || getEnabled()) ) {
+ if (edgesonly->get_inconsistent()) {
+ listener->panelChanged (EvPrShrEdgeOnly, M("GENERAL_INITIALVALUES"));
+ } else if (edgesonly->get_active ()) {
+ listener->panelChanged (EvPrShrEdgeOnly, M("GENERAL_ENABLED"));
+ } else {
+ listener->panelChanged (EvPrShrEdgeOnly, M("GENERAL_DISABLED"));
+ }
+ }
+}
+
+void PrSharpening::halocontrol_toggled ()
+{
+
+ if (multiImage) {
+ if (halocontrol->get_inconsistent()) {
+ halocontrol->set_inconsistent (false);
+ hcConn.block (true);
+ halocontrol->set_active (false);
+ hcConn.block (false);
+ } else if (lastHaloControl) {
+ halocontrol->set_inconsistent (true);
+ }
+
+ lastHaloControl = halocontrol->get_active ();
+ }
+
+ if (!batchMode) {
+ removeIfThere (hcbin, hcbox, false);
+
+ if (halocontrol->get_active ()) {
+ hcbin->pack_start (*hcbox);
+ }
+ }
+
+ if (listener && (multiImage || getEnabled()) ) {
+ if (halocontrol->get_inconsistent()) {
+ listener->panelChanged (EvPrShrHaloControl, M("GENERAL_INITIALVALUES"));
+ } else if (halocontrol->get_active ()) {
+ listener->panelChanged (EvPrShrHaloControl, M("GENERAL_ENABLED"));
+ } else {
+ listener->panelChanged (EvPrShrHaloControl, M("GENERAL_DISABLED"));
+ }
+ }
+}
+
+void PrSharpening::method_changed ()
+{
+
+ removeIfThere (this, usm, false);
+ removeIfThere (this, rld, false);
+
+ if (method->get_active_row_number() == 0) {
+ pack_start (*usm);
+ } else if (method->get_active_row_number() == 1) {
+ pack_start (*rld);
+ }
+
+ if (listener && (multiImage || getEnabled()) ) {
+ listener->panelChanged (EvPrShrMethod, method->get_active_text ());
+ }
+
+}
+
+void PrSharpening::adjusterChanged (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR) {
+ if (listener && (multiImage||getEnabled()) ) {
+ if(a==threshold) {
+ listener->panelChanged (EvPrShrThresh,threshold->getHistoryString());
+ }
+ }
+}
+
+void PrSharpening::setBatchMode (bool batchMode)
+{
+
+ ToolPanel::setBatchMode (batchMode);
+
+ removeIfThere (hcbin, hcbox, false);
+ hcbin->pack_start (*hcbox);
+ removeIfThere (edgebin, edgebox, false);
+ edgebin->pack_start (*edgebox);
+
+ radius->showEditedCB ();
+ amount->showEditedCB ();
+ threshold->showEditedCB ();
+ eradius->showEditedCB ();
+ etolerance->showEditedCB ();
+ hcamount->showEditedCB ();
+ dradius->showEditedCB ();
+ damount->showEditedCB ();
+ ddamping->showEditedCB ();
+ diter->showEditedCB ();
+ method->append_text (M("GENERAL_UNCHANGED"));
+}
+
+void PrSharpening::setAdjusterBehavior (bool amountadd)
+{
+
+ amount->setAddMode(amountadd);
+ damount->setAddMode(amountadd);
+}
+
+void PrSharpening::trimValues (rtengine::procparams::ProcParams* pp)
+{
+
+ amount->trimValue(pp->prsharpening.amount);
+ damount->trimValue(pp->prsharpening.deconvamount);
+}
diff --git a/rtgui/prsharpening.h b/rtgui/prsharpening.h
new file mode 100644
index 000000000..c0739b818
--- /dev/null
+++ b/rtgui/prsharpening.h
@@ -0,0 +1,77 @@
+/*
+ * This file is part of RawTherapee.
+ *
+ * Copyright (c) 2004-2010 Gabor Horvath
+ *
+ * RawTherapee is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * RawTherapee is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with RawTherapee. If not, see .
+ */
+#ifndef _PRSHARPENING_H_
+#define _PRSHARPENING_H_
+
+#include
+#include "adjuster.h"
+#include "thresholdadjuster.h"
+#include "toolpanel.h"
+
+class PrSharpening : public ToolParamBlock, public ThresholdAdjusterListener, public AdjusterListener, public FoldableToolPanel
+{
+
+protected:
+ MyComboBoxText* method;
+ Adjuster* dradius;
+ Adjuster* damount;
+ Adjuster* ddamping;
+ Adjuster* diter;
+ Gtk::VBox* usm;
+ Gtk::VBox* rld;
+
+ Adjuster* radius;
+ Adjuster* amount;
+ Adjuster* eradius;
+ Adjuster* etolerance;
+ Adjuster* hcamount;
+ Gtk::VBox* edgebin;
+ Gtk::VBox* hcbin;
+ Gtk::VBox* edgebox;
+ Gtk::VBox* hcbox;
+ ThresholdAdjuster* threshold;
+ Gtk::CheckButton* edgesonly;
+ bool lastEdgesOnly;
+ sigc::connection eonlyConn;
+ Gtk::CheckButton* halocontrol;
+ bool lastHaloControl;
+ sigc::connection hcConn;
+
+public:
+
+ PrSharpening ();
+ virtual ~PrSharpening ();
+
+ void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited = NULL);
+ 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 adjusterChanged (Adjuster* a, double newval);
+ void enabledChanged ();
+ void edgesonly_toggled ();
+ void halocontrol_toggled ();
+ void method_changed ();
+ void adjusterChanged (ThresholdAdjuster* a, int newBottomL, int newTopL, int newBottomR, int newTopR);
+
+ void setAdjusterBehavior (bool amountadd);
+ void trimValues (rtengine::procparams::ProcParams* pp);
+};
+
+#endif
diff --git a/rtgui/resize.cc b/rtgui/resize.cc
index 5f02def95..58d4c8ac5 100644
--- a/rtgui/resize.cc
+++ b/rtgui/resize.cc
@@ -7,7 +7,7 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
- *
+ *
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -17,16 +17,16 @@
* along with RawTherapee. If not, see .
*/
#include "resize.h"
-#include
#include "guiutils.h"
using namespace rtengine;
using namespace rtengine::procparams;
-Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), false, true), maxw(100000), maxh(100000) {
+Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), false, true), maxw(100000), maxh(100000)
+{
- cropw = 0;
- croph = 0;
+ cropw = 0;
+ croph = 0;
Gtk::Table* combos = Gtk::manage (new Gtk::Table (2, 2));
Gtk::Label *label = NULL;
@@ -41,29 +41,30 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals
combos->attach (*label, 0, 1, 0, 1, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
combos->attach (*appliesTo, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
- method = Gtk::manage (new MyComboBoxText ());
- method->append_text (M("TP_RESIZE_LANCZOS"));
- method->append_text (M("TP_RESIZE_NEAREST"));
- method->set_active (0);
+ // See Resize::methodChanged() when adding a new method.
+ method = Gtk::manage (new MyComboBoxText ());
+ method->append_text (M("TP_RESIZE_LANCZOS"));
+ method->append_text (M("TP_RESIZE_NEAREST"));
+ method->set_active (0);
label = Gtk::manage (new Gtk::Label (M("TP_RESIZE_METHOD")));
label->set_alignment(0., 0.);
combos->attach (*label, 0, 1, 1, 2, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
combos->attach (*method, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
- spec = Gtk::manage (new MyComboBoxText ());
- spec->append_text (M("TP_RESIZE_SCALE"));
- spec->append_text (M("TP_RESIZE_WIDTH"));
- spec->append_text (M("TP_RESIZE_HEIGHT"));
- spec->append_text (M("TP_RESIZE_FITBOX"));
- spec->set_active (0);
-
+ spec = Gtk::manage (new MyComboBoxText ());
+ spec->append_text (M("TP_RESIZE_SCALE"));
+ spec->append_text (M("TP_RESIZE_WIDTH"));
+ spec->append_text (M("TP_RESIZE_HEIGHT"));
+ spec->append_text (M("TP_RESIZE_FITBOX"));
+ spec->set_active (0);
+
label = Gtk::manage (new Gtk::Label (M("TP_RESIZE_SPECIFY")));
label->set_alignment(0., 0.);
- combos->attach (*label, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
+ combos->attach (*label, 0, 1, 2, 3, Gtk::SHRINK, Gtk::SHRINK, 2, 2);
combos->attach (*spec, 1, 2, 2, 3, Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK, 2, 2);
- pack_start (*combos, Gtk::PACK_SHRINK, 4);
+ pack_start (*combos, Gtk::PACK_SHRINK, 4);
scale = new Adjuster (M("TP_RESIZE_SCALE"), 0.01, 4, 0.01, 1.);
scale->setAdjusterListener (this);
@@ -86,37 +87,44 @@ Resize::Resize () : FoldableToolPanel(this, "resize", M("TP_RESIZE_LABEL"), fals
sbox->set_spacing(4);
sbox->pack_start (*wbox);
sbox->pack_start (*hbox);
-
+
sizeBox->pack_start (*sbox, Gtk::PACK_SHRINK, 0);
sizeBox->show_all ();
sizeBox->reference ();
-
+
w->set_digits (0);
- w->set_increments (1,100);
+ w->set_increments (1, 100);
w->set_value (800);
- w->set_range (32, 4*maxw);
+ w->set_range (32, 4 * maxw);
h->set_digits (0);
- h->set_increments (1,100);
+ h->set_increments (1, 100);
h->set_value (600);
- h->set_range (32, 4*maxh);
+ h->set_range (32, 4 * maxh);
wconn = w->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryWChanged), true);
hconn = h->signal_value_changed().connect ( sigc::mem_fun(*this, &Resize::entryHChanged), true);
- aconn = appliesTo->signal_changed().connect ( sigc::mem_fun(*this, &Resize::appliesToChanged) );
- method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) );
- sconn = spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) );
+ aconn = appliesTo->signal_changed().connect ( sigc::mem_fun(*this, &Resize::appliesToChanged) );
+ method->signal_changed().connect ( sigc::mem_fun(*this, &Resize::methodChanged) );
+ sconn = spec->signal_changed().connect ( sigc::mem_fun(*this, &Resize::specChanged) );
+
+ packBox = Gtk::manage (new ToolParamBlock ());
+ pack_end (*packBox);
+ packBox->hide();
+ packBox->set_tooltip_markup (M("TP_PRSHARPENING_TOOLTIP"));
show_all();
}
-Resize::~Resize () {
+Resize::~Resize ()
+{
delete scale;
delete sizeBox;
}
-void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) {
+void Resize::read (const ProcParams* pp, const ParamsEdited* pedited)
+{
disableListener ();
aconn.block (true);
@@ -133,17 +141,20 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) {
updateGUI();
appliesTo->set_active (0);
- if (pp->resize.appliesTo == "Cropped area")
- appliesTo->set_active (0);
- else if (pp->resize.appliesTo == "Full image")
- appliesTo->set_active (1);
- if (pp->resize.method == "Lanczos")
+ if (pp->resize.appliesTo == "Cropped area") {
+ appliesTo->set_active (0);
+ } else if (pp->resize.appliesTo == "Full image") {
+ appliesTo->set_active (1);
+ }
+
+ if (pp->resize.method == "Lanczos") {
method->set_active (0);
- else if (pp->resize.method == "Nearest")
+ } else if (pp->resize.method == "Nearest") {
method->set_active (1);
- else
+ } else {
method->set_active (0);
+ }
wDirty = false;
hDirty = false;
@@ -152,12 +163,19 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) {
wDirty = pedited->resize.width;
hDirty = pedited->resize.height;
scale->setEditedState (pedited->resize.scale ? Edited : UnEdited);
- if (!pedited->resize.appliesTo)
+
+ if (!pedited->resize.appliesTo) {
appliesTo->set_active (2);
- if (!pedited->resize.method)
+ }
+
+ if (!pedited->resize.method) {
method->set_active (3);
- if (!pedited->resize.dataspec)
+ }
+
+ if (!pedited->resize.dataspec) {
spec->set_active (4);
+ }
+
set_inconsistent (multiImage && !pedited->resize.enabled);
}
@@ -169,23 +187,28 @@ void Resize::read (const ProcParams* pp, const ParamsEdited* pedited) {
enableListener ();
}
-void Resize::write (ProcParams* pp, ParamsEdited* pedited) {
- int dataSpec = spec->get_active_row_number();
+void Resize::write (ProcParams* pp, ParamsEdited* pedited)
+{
+ int dataSpec = spec->get_active_row_number();
pp->resize.scale = scale->getValue();
pp->resize.appliesTo = "Cropped area";
- if (appliesTo->get_active_row_number() == 0)
+
+ if (appliesTo->get_active_row_number() == 0) {
pp->resize.appliesTo = "Cropped area";
- else if (appliesTo->get_active_row_number() == 1)
+ } else if (appliesTo->get_active_row_number() == 1) {
pp->resize.appliesTo = "Full image";
+ }
pp->resize.method = "Lanczos";
- if (method->get_active_row_number() == 0)
+
+ if (method->get_active_row_number() == 0) {
pp->resize.method = "Lanczos";
- else if (method->get_active_row_number() == 1)
+ } else if (method->get_active_row_number() == 1) {
pp->resize.method = "Nearest";
-
+ }
+
pp->resize.dataspec = dataSpec;
pp->resize.width = w->get_value_as_int ();
pp->resize.height = h->get_value_as_int ();
@@ -197,12 +220,12 @@ void Resize::write (ProcParams* pp, ParamsEdited* pedited) {
pedited->resize.dataspec = dataSpec != 4;
pedited->resize.appliesTo = appliesTo->get_active_row_number() != 2;
pedited->resize.method = method->get_active_row_number() != 3;
+
if (pedited->resize.dataspec) {
pedited->resize.scale = scale->getEditedState ();
pedited->resize.width = wDirty;
pedited->resize.height = hDirty;
- }
- else {
+ } else {
pedited->resize.scale = false;
pedited->resize.width = false;
pedited->resize.height = false;
@@ -210,77 +233,100 @@ void Resize::write (ProcParams* pp, ParamsEdited* pedited) {
}
}
-void Resize::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
+void Resize::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited)
+{
scale->setDefault (defParams->resize.scale);
- if (pedited)
+ if (pedited) {
scale->setDefaultEditedState (pedited->resize.scale ? Edited : UnEdited);
- else
+ } else {
scale->setDefaultEditedState (Irrelevant);
+ }
}
-void Resize::adjusterChanged (Adjuster* a, double newval) {
+void Resize::adjusterChanged (Adjuster* a, double newval)
+{
if (!batchMode) {
wconn.block (true);
hconn.block (true);
- h->set_value ((croph && appliesTo->get_active_row_number()==0 ? croph : maxh) * a->getValue ());
- w->set_value ((cropw && appliesTo->get_active_row_number()==0 ? cropw : maxw) * a->getValue ());
+ h->set_value ((croph && appliesTo->get_active_row_number() == 0 ? croph : maxh) * a->getValue ());
+ w->set_value ((cropw && appliesTo->get_active_row_number() == 0 ? cropw : maxw) * a->getValue ());
wconn.block (false);
hconn.block (false);
}
- if (listener && (getEnabled () || batchMode))
- listener->panelChanged (EvResizeScale, Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(2), scale->getValue()));
-}
-
-int Resize::getComputedWidth() {
-
- if (cropw && appliesTo->get_active_row_number()==0)
- // we use the crop dimensions
- return (int)((double)(cropw) * (h->get_value()/(double)(croph)) + 0.5);
- else
- // we use the image dimensions
- return (int)((double)(maxw) * (h->get_value()/(double)(maxh)) + 0.5);
-}
-
-int Resize::getComputedHeight() {
-
- if (croph && appliesTo->get_active_row_number()==0)
- // we use the crop dimensions
- return (int)((double)(croph) * (w->get_value()/(double)(cropw)) + 0.5);
- else
- // we use the image dimensions
- return (int)((double)(maxh) * (w->get_value()/(double)(maxw)) + 0.5);
-}
-
-void Resize::appliesToChanged () {
-
- //printf("\nPASSAGE EN MODE \"%s\"\n\n", appliesTo->get_active_text().c_str());
- setDimensions();
if (listener && (getEnabled () || batchMode)) {
- //printf("Appel du listener\n");
+ listener->panelChanged (EvResizeScale, Glib::ustring::format (std::setw(5), std::fixed, std::setprecision(2), scale->getValue()));
+ }
+}
+
+int Resize::getComputedWidth()
+{
+
+ if (cropw && appliesTo->get_active_row_number() == 0)
+ // we use the crop dimensions
+ {
+ return (int)((double)(cropw) * (h->get_value() / (double)(croph)) + 0.5);
+ } else
+ // we use the image dimensions
+ {
+ return (int)((double)(maxw) * (h->get_value() / (double)(maxh)) + 0.5);
+ }
+}
+
+int Resize::getComputedHeight()
+{
+
+ if (croph && appliesTo->get_active_row_number() == 0)
+ // we use the crop dimensions
+ {
+ return (int)((double)(croph) * (w->get_value() / (double)(cropw)) + 0.5);
+ } else
+ // we use the image dimensions
+ {
+ return (int)((double)(maxh) * (w->get_value() / (double)(maxw)) + 0.5);
+ }
+}
+
+void Resize::appliesToChanged ()
+{
+
+ //printf("\nPASSAGE EN MODE \"%s\"\n\n", appliesTo->get_active_text().c_str());
+ setDimensions();
+
+ if (listener && (getEnabled () || batchMode)) {
+ //printf("Appel du listener\n");
listener->panelChanged (EvResizeAppliesTo, appliesTo->get_active_text());
}
}
-void Resize::methodChanged () {
+void Resize::methodChanged ()
+{
- if (listener && (getEnabled () || batchMode))
+ if (listener && (getEnabled () || batchMode)) {
listener->panelChanged (EvResizeMethod, method->get_active_text());
+ }
+
+ // Post-resize Sharpening assumes the image is in Lab space, and currently Lanczos is the only method which uses that space, and Lanczos is on row 0.
+ if (method->get_active_row_number() == 0) {
+ packBox->set_sensitive(true);
+ } else {
+ packBox->set_sensitive(false);
+ }
}
-void Resize::update (bool isCropped, int cw, int ch, int ow, int oh) {
+void Resize::update (bool isCropped, int cw, int ch, int ow, int oh)
+{
- // updating crop values now
+ // updating crop values now
if (isCropped) {
- cropw = cw;
- croph = ch;
- }
- else {
- cropw = 0;
- croph = 0;
+ cropw = cw;
+ croph = ch;
+ } else {
+ cropw = 0;
+ croph = 0;
}
// updating the full image dimensions
@@ -288,13 +334,15 @@ void Resize::update (bool isCropped, int cw, int ch, int ow, int oh) {
maxw = ow;
maxh = oh;
}
+
// updating the GUI synchronously
setDimensions();
}
-void Resize::sizeChanged (int mw, int mh, int ow, int oh) {
+void Resize::sizeChanged (int mw, int mh, int ow, int oh)
+{
- // updating max values now
+ // updating max values now
maxw = ow;
maxh = oh;
@@ -302,7 +350,8 @@ void Resize::sizeChanged (int mw, int mh, int ow, int oh) {
setDimensions();
}
-void Resize::setDimensions () {
+void Resize::setDimensions ()
+{
int refw, refh;
@@ -310,50 +359,56 @@ void Resize::setDimensions () {
hconn.block (true);
scale->block(true);
- if (appliesTo->get_active_row_number()==0 && cropw) {
- // Applies to Cropped area
- refw = cropw;
- refh = croph;
+ if (appliesTo->get_active_row_number() == 0 && cropw) {
+ // Applies to Cropped area
+ refw = cropw;
+ refh = croph;
+ } else {
+ // Applies to Full image or crop is disabled
+ refw = maxw;
+ refh = maxh;
}
- else {
- // Applies to Full image or crop is disabled
- refw = maxw;
- refh = maxh;
- }
- GThreadLock lock;
- w->set_range (32, 4*refw);
- h->set_range (32, 4*refh);
- double tmpScale;
+ GThreadLock lock;
+ w->set_range (32, 4 * refw);
+ h->set_range (32, 4 * refh);
+
+ double tmpScale;
+
switch (spec->get_active_row_number()) {
- case (0): // Scale mode
+ case (0): // Scale mode
w->set_value((double)((int)( (double)(refw) * scale->getValue() + 0.5) ));
h->set_value((double)((int)( (double)(refh) * scale->getValue() + 0.5) ));
break;
- case (1): // Width mode
- tmpScale = w->get_value() / (double)refw;
- scale->setValue (tmpScale);
- h->set_value((double)((int)( (double)(refh) * tmpScale + 0.5) ));
+
+ case (1): // Width mode
+ tmpScale = w->get_value() / (double)refw;
+ scale->setValue (tmpScale);
+ h->set_value((double)((int)( (double)(refh) * tmpScale + 0.5) ));
break;
- case (2): // Height mode
- tmpScale = h->get_value() / (double)refh;
- scale->setValue (tmpScale);
- w->set_value((double)((int)( (double)(refw) * tmpScale + 0.5) ));
- break;
- case (3): { // Bounding box mode
- double wSliderValue = w->get_value();
- double hSliderValue = h->get_value();
- if ( (wSliderValue/hSliderValue) < ((double)refw/(double)refh)) {
- tmpScale = wSliderValue / (double)refw;
- }
- else {
- tmpScale = hSliderValue / (double)refh;
- }
- scale->setValue (tmpScale);
+
+ case (2): // Height mode
+ tmpScale = h->get_value() / (double)refh;
+ scale->setValue (tmpScale);
+ w->set_value((double)((int)( (double)(refw) * tmpScale + 0.5) ));
break;
- }
+
+ case (3): { // Bounding box mode
+ double wSliderValue = w->get_value();
+ double hSliderValue = h->get_value();
+
+ if ( (wSliderValue / hSliderValue) < ((double)refw / (double)refh)) {
+ tmpScale = wSliderValue / (double)refw;
+ } else {
+ tmpScale = hSliderValue / (double)refh;
+ }
+
+ scale->setValue (tmpScale);
+ break;
+ }
+
default:
- break;
+ break;
}
scale->block(false);
@@ -361,129 +416,137 @@ void Resize::setDimensions () {
hconn.block (false);
}
-void Resize::fitBoxScale() {
- double tmpScale;
- double neww = w->get_value ();
- double newh = h->get_value ();
+void Resize::fitBoxScale()
+{
+ double tmpScale;
+ double neww = w->get_value ();
+ double newh = h->get_value ();
- if (cropw && appliesTo->get_active_row_number()==0) {
- // we use the crop dimensions
- if (((double)(cropw) / (double)(croph)) > (neww / newh)) {
- // the new scale is given by the image width
- tmpScale = neww / (double)(cropw);
- }
- else {
- // the new scale is given by the image height
- tmpScale = newh / (double)(croph);
- }
- }
- else {
- // we use the image dimensions
- if (((double)(maxw) / (double)(maxh)) > (neww / newh)) {
- // the new scale is given by the image width
- tmpScale = neww / (double)(maxw);
- }
- else {
- // the new scale is given by the image height
- tmpScale = newh / (double)(maxh);
- }
- }
- scale->setValue (tmpScale);
+ if (cropw && appliesTo->get_active_row_number() == 0) {
+ // we use the crop dimensions
+ if (((double)(cropw) / (double)(croph)) > (neww / newh)) {
+ // the new scale is given by the image width
+ tmpScale = neww / (double)(cropw);
+ } else {
+ // the new scale is given by the image height
+ tmpScale = newh / (double)(croph);
+ }
+ } else {
+ // we use the image dimensions
+ if (((double)(maxw) / (double)(maxh)) > (neww / newh)) {
+ // the new scale is given by the image width
+ tmpScale = neww / (double)(maxw);
+ } else {
+ // the new scale is given by the image height
+ tmpScale = newh / (double)(maxh);
+ }
+ }
+
+ scale->setValue (tmpScale);
}
-void Resize::entryWChanged () {
+void Resize::entryWChanged ()
+{
wDirty = true;
// updating width
if (!batchMode) {
- if (spec->get_active_row_number() == 3) {
- // Fit box mode
- fitBoxScale();
- }
- else {
- // Other modes
- hconn.block (true);
- scale->block (true);
+ if (spec->get_active_row_number() == 3) {
+ // Fit box mode
+ fitBoxScale();
+ } else {
+ // Other modes
+ hconn.block (true);
+ scale->block (true);
- h->set_value ((double)(getComputedHeight()));
- scale->setValue (w->get_value () / (cropw && appliesTo->get_active_row_number()==0 ? (double)cropw : (double)maxw));
+ h->set_value ((double)(getComputedHeight()));
+ scale->setValue (w->get_value () / (cropw && appliesTo->get_active_row_number() == 0 ? (double)cropw : (double)maxw));
- scale->block (false);
- hconn.block (false);
- }
+ scale->block (false);
+ hconn.block (false);
+ }
}
if (listener) {
- if (spec->get_active_row_number() == 3)
- notifyBBox();
- else {
- if (getEnabled () || batchMode)
- listener->panelChanged (EvResizeWidth, Glib::ustring::format (w->get_value_as_int()));
- }
+ if (spec->get_active_row_number() == 3) {
+ notifyBBox();
+ } else {
+ if (getEnabled () || batchMode) {
+ listener->panelChanged (EvResizeWidth, Glib::ustring::format (w->get_value_as_int()));
+ }
+ }
}
}
-void Resize::entryHChanged () {
+void Resize::entryHChanged ()
+{
hDirty = true;
if (!batchMode && listener) {
- if (spec->get_active_row_number() == 3) {
- // Fit box mode
- fitBoxScale();
- }
- else {
- // Other modes
+ if (spec->get_active_row_number() == 3) {
+ // Fit box mode
+ fitBoxScale();
+ } else {
+ // Other modes
wconn.block (true);
- scale->block (true);
+ scale->block (true);
w->set_value ((double)(getComputedWidth()));
- scale->setValue (h->get_value () / (croph && appliesTo->get_active_row_number()==0 ? (double)croph : (double)maxh));
+ scale->setValue (h->get_value () / (croph && appliesTo->get_active_row_number() == 0 ? (double)croph : (double)maxh));
- scale->block (false);
+ scale->block (false);
wconn.block (false);
- }
+ }
}
if (listener) {
- if (spec->get_active_row_number() == 3)
- notifyBBox();
- else {
- if (getEnabled () || batchMode)
- listener->panelChanged (EvResizeHeight, Glib::ustring::format (h->get_value_as_int()));
- }
+ if (spec->get_active_row_number() == 3) {
+ notifyBBox();
+ } else {
+ if (getEnabled () || batchMode) {
+ listener->panelChanged (EvResizeHeight, Glib::ustring::format (h->get_value_as_int()));
+ }
+ }
}
}
-void Resize::specChanged () {
+void Resize::specChanged ()
+{
switch (spec->get_active_row_number()) {
case (0):
// Scale mode
scale->sliderChanged ();
break;
+
case (1):
// Width mode
w->set_value((double)(getComputedWidth()));
entryWChanged ();
break;
+
case (2):
// Height mode
h->set_value((double)(getComputedHeight()));
entryHChanged ();
break;
+
case (3):
// Bounding box mode
notifyBBox();
break;
+
default:
break;
}
+
updateGUI();
}
-void Resize::updateGUI () {
+void Resize::updateGUI ()
+{
removeIfThere (this, scale, false);
removeIfThere (this, sizeBox, false);
@@ -493,51 +556,60 @@ void Resize::updateGUI () {
// Scale mode
pack_start (*scale, Gtk::PACK_SHRINK, 4);
break;
+
case (1):
// Width mode
pack_start (*sizeBox, Gtk::PACK_SHRINK, 4);
w->set_sensitive (true);
h->set_sensitive (false);
break;
+
case (2):
// Height mode
pack_start (*sizeBox, Gtk::PACK_SHRINK, 4);
w->set_sensitive (false);
h->set_sensitive (true);
break;
+
case (3):
// Bounding box mode
pack_start (*sizeBox, Gtk::PACK_SHRINK, 4);
w->set_sensitive (true);
h->set_sensitive (true);
break;
+
default:
break;
}
}
-void Resize::notifyBBox() {
- if (listener && (getEnabled () || batchMode))
- listener->panelChanged (EvResizeBoundingBox, Glib::ustring::compose("(%1x%2)",(int)w->get_value(), (int)h->get_value() ));
+void Resize::notifyBBox()
+{
+ if (listener && (getEnabled () || batchMode)) {
+ listener->panelChanged (EvResizeBoundingBox, Glib::ustring::compose("(%1x%2)", (int)w->get_value(), (int)h->get_value() ));
+ }
}
-void Resize::setBatchMode (bool batchMode) {
+void Resize::setBatchMode (bool batchMode)
+{
- method->append_text (M("GENERAL_UNCHANGED"));
- spec->append_text (M("GENERAL_UNCHANGED"));
+ method->append_text (M("GENERAL_UNCHANGED"));
+ spec->append_text (M("GENERAL_UNCHANGED"));
ToolPanel::setBatchMode (batchMode);
scale->showEditedCB ();
}
-void Resize::enabledChanged () {
+void Resize::enabledChanged ()
+{
if (listener) {
- if (get_inconsistent())
+ if (get_inconsistent()) {
listener->panelChanged (EvResizeEnabled, M("GENERAL_UNCHANGED"));
- else if (getEnabled())
+ } else if (getEnabled()) {
listener->panelChanged (EvResizeEnabled, M("GENERAL_ENABLED"));
- else
+ } else {
listener->panelChanged (EvResizeEnabled, M("GENERAL_DISABLED"));
+ }
}
}
diff --git a/rtgui/resize.h b/rtgui/resize.h
index cc4934c6a..54bfb4e4a 100644
--- a/rtgui/resize.h
+++ b/rtgui/resize.h
@@ -39,12 +39,15 @@ class Resize : public ToolParamBlock, public AdjusterListener, public FoldableTo
int cropw, croph;
sigc::connection sconn, aconn, wconn, hconn;
bool wDirty, hDirty;
+ ToolParamBlock* packBox;
public:
Resize ();
~Resize ();
+ Gtk::Box* getPackBox () { return packBox; }
+
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc
index 434f11604..d9dabf971 100644
--- a/rtgui/toolpanelcoord.cc
+++ b/rtgui/toolpanelcoord.cc
@@ -25,8 +25,6 @@
#include "../rtengine/improcfun.h"
#include "../rtengine/procevents.h"
#include "../rtengine/refreshmap.h"
-#include "guiutils.h"
-#include "rtimage.h"
using namespace rtengine::procparams;
@@ -67,6 +65,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
chmixer = Gtk::manage (new ChMixer ());
blackwhite = Gtk::manage (new BlackWhite ());
resize = Gtk::manage (new Resize ());
+ prsharpening = Gtk::manage (new PrSharpening());
crop = Gtk::manage (new Crop ());
icm = Gtk::manage (new ICMPanel ());
exifpanel = Gtk::manage (new ExifPanel ());
@@ -122,6 +121,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (waveletPanel, wavelet); toolPanels.push_back (wavelet);
addPanel (transformPanel, crop); toolPanels.push_back (crop);
addPanel (transformPanel, resize); toolPanels.push_back (resize);
+ addPanel (resize->getPackBox(), prsharpening); toolPanels.push_back (prsharpening);
addPanel (transformPanel, lensgeom); toolPanels.push_back (lensgeom);
addPanel (lensgeom->getPackBox(), rotate); toolPanels.push_back (rotate);
addPanel (lensgeom->getPackBox(), perspective); toolPanels.push_back (perspective);
@@ -142,8 +142,6 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (rawPanel, preprocess); toolPanels.push_back (preprocess);
addPanel (rawPanel, darkframe); toolPanels.push_back (darkframe);
addPanel (rawPanel, flatfield); toolPanels.push_back (flatfield);
-
-
toolPanels.push_back (coarse);
toolPanels.push_back (exifpanel);
diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h
index c9913492c..2ada0556d 100644
--- a/rtgui/toolpanelcoord.h
+++ b/rtgui/toolpanelcoord.h
@@ -77,6 +77,7 @@
#include "rgbcurves.h"
#include "colortoning.h"
#include "filmsimulation.h"
+#include "prsharpening.h"
#include "guiutils.h"
class ImageEditorCoordinator;
@@ -111,6 +112,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
ChMixer* chmixer;
BlackWhite* blackwhite;
Resize* resize;
+ PrSharpening* prsharpening;
ICMPanel* icm;
Crop* crop;
ToneCurve* toneCurve;