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;