diff --git a/rtdata/languages/English (UK) b/rtdata/languages/English (UK) index b96535923..1c21042ab 100644 --- a/rtdata/languages/English (UK) +++ b/rtdata/languages/English (UK) @@ -3757,7 +3757,9 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor !TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length +!TP_PERSPECTIVE_CAMERA_DEFISH;De-fish !TP_PERSPECTIVE_CAMERA_FRAME;Correction +!TP_PERSPECTIVE_CAMERA_SCALE;Scale !TP_PERSPECTIVE_CAMERA_PITCH;Vertical !TP_PERSPECTIVE_CAMERA_ROLL;Rotation !TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontal shift @@ -3774,6 +3776,7 @@ TP_WBALANCE_PATCHLABEL_TOOLTIP;Display number of read colours (max=237).\nDispla !TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correction adjustment !TP_PERSPECTIVE_PROJECTION_PITCH;Vertical !TP_PERSPECTIVE_PROJECTION_ROTATE;Rotation +!TP_PERSPECTIVE_CAMERA_SCALE;Scale !TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontal shift !TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Vertical shift !TP_PERSPECTIVE_PROJECTION_YAW;Horizontal diff --git a/rtdata/languages/English (US) b/rtdata/languages/English (US) index 1e7630225..99d3ae057 100644 --- a/rtdata/languages/English (US) +++ b/rtdata/languages/English (US) @@ -3726,7 +3726,9 @@ !TP_PDSHARPENING_LABEL;Capture Sharpening !TP_PERSPECTIVE_CAMERA_CROP_FACTOR;Crop factor !TP_PERSPECTIVE_CAMERA_FOCAL_LENGTH;Focal length +!TP_PERSPECTIVE_CAMERA_DEFISH;De-fish !TP_PERSPECTIVE_CAMERA_FRAME;Correction +!TP_PERSPECTIVE_CAMERA_SCALE;Scale !TP_PERSPECTIVE_CAMERA_PITCH;Vertical !TP_PERSPECTIVE_CAMERA_ROLL;Rotation !TP_PERSPECTIVE_CAMERA_SHIFT_HORIZONTAL;Horizontal shift @@ -3743,6 +3745,7 @@ !TP_PERSPECTIVE_POST_CORRECTION_ADJUSTMENT_FRAME;Post-correction adjustment !TP_PERSPECTIVE_PROJECTION_PITCH;Vertical !TP_PERSPECTIVE_PROJECTION_ROTATE;Rotation +!TP_PERSPECTIVE_CAMERA_SCALE;Scale !TP_PERSPECTIVE_PROJECTION_SHIFT_HORIZONTAL;Horizontal shift !TP_PERSPECTIVE_PROJECTION_SHIFT_VERTICAL;Vertical shift !TP_PERSPECTIVE_PROJECTION_YAW;Horizontal diff --git a/rtdata/languages/default b/rtdata/languages/default index bf7402629..e3437d07c 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1412,6 +1412,8 @@ HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness +HISTORY_MSG_DISTORTION_DEFISH;De-fish +HISTORY_MSG_DISTORTION_DEFISH_FOCAL;De-fish - Focal length HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_EDGEFFECT;Edge Attenuation response @@ -1575,6 +1577,7 @@ HISTORY_MSG_TONE_EQUALIZER_ENABLED;Tone equalizer HISTORY_MSG_TONE_EQUALIZER_PIVOT;Tone equalizer - Pivot HISTORY_MSG_TONE_EQUALIZER_REGULARIZATION;Tone equalizer - Regularization HISTORY_MSG_TONE_EQUALIZER_SHOW_COLOR_MAP;Tone equalizer - Tonal map +HISTORY_MSG_TRANS_SCALE;Geometry - Scale HISTORY_MSG_TRANS_METHOD;Geometry - Method HISTORY_MSG_WAVBALCHROM;Equalizer chrominance HISTORY_MSG_WAVBALLUM;Equalizer luminance @@ -2603,6 +2606,8 @@ TP_DIRPYREQUALIZER_THRESHOLD;Threshold TP_DIRPYREQUALIZER_TOOLTIP;Attempts to reduce artifacts in the transitions between skin colors (hue, chroma, luma) and the rest of the image. TP_DISTORTION_AMOUNT;Amount TP_DISTORTION_AUTO_TOOLTIP;Automatically corrects lens distortion in raw files by matching it against the embedded JPEG image if one exists and has had its lens disortion auto-corrected by the camera. +TP_DISTORTION_DEFISH;De-fish +TP_DISTORTION_FOCAL_LENGTH;Focal length TP_DISTORTION_LABEL;Distortion Correction TP_EPD_EDGESTOPPING;Edge stopping TP_EPD_GAMMA;Gamma @@ -2839,6 +2844,7 @@ TP_LABCURVE_LCREDSK_TOOLTIP;If enabled, the LC Curve affects only red and skin-t TP_LABCURVE_RSTPROTECTION;Red and skin-tones protection TP_LABCURVE_RSTPRO_TOOLTIP;Works on the Chromaticity slider and the CC curve. TP_LENSGEOM_AUTOCROP;Auto-Crop +TP_LENSGEOM_SCALE;Scale TP_LENSGEOM_FILL;Auto-fill TP_LENSGEOM_LABEL;Lens / Geometry TP_LENSGEOM_LIN;Linear diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index c8c6e166e..db07fd91f 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -127,6 +127,7 @@ class ImProcFunctions bool needsDistortion() const; bool needsRotation() const; bool needsPerspective() const; + bool needsScale() const; bool needsGradient() const; bool needsVignetting() const; bool needsLCP() const; diff --git a/rtengine/iptransform.cc b/rtengine/iptransform.cc index 10f37e781..c75a8c1ea 100644 --- a/rtengine/iptransform.cc +++ b/rtengine/iptransform.cc @@ -431,7 +431,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, green.clear (); blue.clear (); - if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective() && (!params->lensProf.useDist || pLCPMap == nullptr)) { + if (!needsCA() && !needsDistortion() && !needsRotation() && !needsPerspective() && !needsScale() && (!params->lensProf.useDist || pLCPMap == nullptr)) { for (size_t i = 0; i < src.size(); i++) { red.push_back (Coord2D (src[i].x, src[i].y)); green.push_back (Coord2D (src[i].x, src[i].y)); @@ -454,7 +454,7 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, double cost = cos (params->rotate.degree * rtengine::RT_PI / 180.0); double sint = sin (params->rotate.degree * rtengine::RT_PI / 180.0); - double ascale = ascaleDef > 0 ? ascaleDef : (params->commonTrans.autofill && params->perspective.render ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0); + double ascale = ascaleDef > 0 ? ascaleDef : (params->commonTrans.autofill && params->perspective.render ? getTransformAutoFill (oW, oH, pLCPMap) : 1.0 / params->commonTrans.getScale()); // auxiliary variables for perspective correction // Simple. @@ -471,6 +471,9 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, ((params->perspective.camera_focal_length > 0) ? params->perspective.camera_focal_length : PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH) * ((params->perspective.camera_crop_factor > 0) ? params->perspective.camera_crop_factor : PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR) * (maxRadius / sqrt(18.0*18.0 + 12.0*12.0)); + const double f_defish = + ((params->distortion.focal_length > 0) ? params->distortion.focal_length : DistortionParams::DEFAULT_FOCAL_LENGTH) + * (maxRadius / sqrt(18.0*18.0 + 12.0*12.0)); const double p_camera_yaw = params->perspective.camera_yaw / 180.0 * rtengine::RT_PI; const double p_camera_pitch = params->perspective.camera_pitch / 180.0 * rtengine::RT_PI; const double p_camera_roll = params->perspective.camera_roll * rtengine::RT_PI_180; @@ -515,6 +518,18 @@ bool ImProcFunctions::transCoord (int W, int H, const std::vector &src, break; } + if (params->distortion.defish) { + x_d /= f_defish; + y_d /= f_defish; + + const double r = std::sqrt(x_d * x_d + y_d * y_d); + + const double factor = f_defish * std::atan(r) / r; + + x_d *= factor; + y_d *= factor; + } + // rotate double Dx = x_d * cost - y_d * sint; double Dy = x_d * sint + y_d * cost; @@ -682,7 +697,7 @@ void ImProcFunctions::transform (Imagefloat* original, Imagefloat* transformed, } } - if (! (needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsLCP() || needsMetadata() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient())) { + if (! (needsCA() || needsDistortion() || needsRotation() || needsPerspective() || needsScale() || needsLCP() || needsMetadata() || needsLensfun()) && (needsVignetting() || needsPCVignetting() || needsGradient())) { transformLuminanceOnly (original, transformed, cx, cy, oW, oH, fW, fH); } else { bool highQuality; @@ -1157,6 +1172,9 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I ((params->perspective.camera_focal_length > 0) ? params->perspective.camera_focal_length : PerspectiveParams::DEFAULT_CAMERA_FOCAL_LENGTH) * ((params->perspective.camera_crop_factor > 0) ? params->perspective.camera_crop_factor : PerspectiveParams::DEFAULT_CAMERA_CROP_FACTOR) * (maxRadius / sqrt(18.0*18.0 + 12.0*12.0)); + const double f_defish = + ((params->distortion.focal_length > 0) ? params->distortion.focal_length : DistortionParams::DEFAULT_FOCAL_LENGTH) + * (maxRadius / sqrt(18.0*18.0 + 12.0*12.0)); const double p_camera_yaw = params->perspective.camera_yaw / 180.0 * rtengine::RT_PI; const double p_camera_pitch = params->perspective.camera_pitch / 180.0 * rtengine::RT_PI; const double p_camera_roll = params->perspective.camera_roll * rtengine::RT_PI_180; @@ -1174,7 +1192,7 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I p_projection_rotate, p_projection_shift_horiz, p_projection_shift_vert, p_projection_scale); - const double ascale = params->commonTrans.autofill && params->perspective.render ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0; + const double ascale = params->commonTrans.autofill && params->perspective.render ? getTransformAutoFill(oW, oH, pLCPMap) : 1.0 / params->commonTrans.getScale(); const bool darkening = (params->vignetting.amount <= 0.0); const bool useLog = params->commonTrans.method == "log" && highQuality; @@ -1232,6 +1250,17 @@ void ImProcFunctions::transformGeneral(bool highQuality, Imagefloat *original, I break; } + if (params->distortion.defish) { + x_d /= f_defish; + y_d /= f_defish; + + const double r = std::sqrt(x_d * x_d + y_d * y_d); + const double factor = f_defish * std::atan(r) / r; + + x_d *= factor; + y_d *= factor; + } + // rotate const double Dxr = x_d * cost - y_d * sint; const double Dyr = x_d * sint + y_d * cost; @@ -1388,7 +1417,9 @@ bool ImProcFunctions::needsCA () const bool ImProcFunctions::needsDistortion () const { - return fabs (params->distortion.amount) > 1e-15; + return + params->distortion.defish || + fabs (params->distortion.amount) > 1e-15; } bool ImProcFunctions::needsRotation () const @@ -1411,7 +1442,12 @@ bool ImProcFunctions::needsPerspective () const params->perspective.projection_rotate || params->perspective.projection_shift_horiz || params->perspective.projection_shift_vert || - params->perspective.projection_yaw) ); + params->perspective.projection_yaw)); +} + +bool ImProcFunctions::needsScale () const +{ + return std::abs(1.0 - params->commonTrans.getScale()) > 1e-6; } bool ImProcFunctions::needsGradient () const @@ -1451,7 +1487,7 @@ bool ImProcFunctions::needsTransform (int oW, int oH, int rawRotationDeg, const std::unique_ptr pLCPMap = LFDatabase::getInstance()->findModifier(params->lensProf, metadata, oW, oH, params->coarse, rawRotationDeg); needsLf = pLCPMap.get(); } - return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsMetadata() || needsLf; + return needsCA () || needsDistortion () || needsRotation () || needsPerspective () || needsScale () || needsGradient () || needsPCVignetting () || needsVignetting () || needsLCP() || needsMetadata() || needsLf; } diff --git a/rtengine/perspectivecorrection.cc b/rtengine/perspectivecorrection.cc index 7a56ef5a8..5494d9ac8 100644 --- a/rtengine/perspectivecorrection.cc +++ b/rtengine/perspectivecorrection.cc @@ -304,8 +304,13 @@ PerspectiveCorrection::Params PerspectiveCorrection::autocompute(ImageSource *sr // TODO: Ensure image borders of rotated image do not get detected as lines. neutral.rotate = pparams->rotate; neutral.distortion = pparams->distortion; + neutral.distortion.defish = pparams->distortion.defish; + neutral.distortion.focal_length = pparams->distortion.focal_length; + neutral.perspective.camera_focal_length = pparams->perspective.camera_focal_length; + neutral.perspective.camera_crop_factor = pparams->perspective.camera_crop_factor; + neutral.perspective.method = pparams->perspective.method; neutral.lensProf = pparams->lensProf; - ImProcFunctions ipf(&neutral, true); + ImProcFunctions ipf(&neutral, true); if (ipf.needsTransform(w, h, src->getRotateDegree(), src->getMetaData())) { Imagefloat *tmp = new Imagefloat(w, h); ipf.transform(img.get(), tmp, 0, 0, 0, 0, w, h, w, h, diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 69b17223e..9398af56b 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1974,13 +1974,19 @@ bool CoarseTransformParams::operator !=(const CoarseTransformParams& other) cons CommonTransformParams::CommonTransformParams() : method("log"), - autofill(true) + autofill(true), + scale(1.0) { } +double CommonTransformParams::getScale() const +{ + return autofill ? 1.0 : scale; +} + bool CommonTransformParams::operator ==(const CommonTransformParams& other) const { - return method == other.method && autofill == other.autofill; + return method == other.method && autofill == other.autofill && std::abs(scale - other.scale) < 1e-6; } bool CommonTransformParams::operator !=(const CommonTransformParams& other) const @@ -2003,14 +2009,11 @@ bool RotateParams::operator !=(const RotateParams& other) const return !(*this == other); } -DistortionParams::DistortionParams() : - amount(0.0) -{ -} +DistortionParams::DistortionParams() {} bool DistortionParams::operator ==(const DistortionParams& other) const { - return amount == other.amount; + return amount == other.amount && defish == other.defish && focal_length == other.focal_length; } bool DistortionParams::operator !=(const DistortionParams& other) const @@ -6760,6 +6763,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Common properties for transformations saveToKeyfile(!pedited || pedited->commonTrans.method, "Common Properties for Transformations", "Method", commonTrans.method, keyFile); + saveToKeyfile(!pedited || pedited->commonTrans.scale, "Common Properties for Transformations", "Scale", commonTrans.scale, keyFile); saveToKeyfile(!pedited || pedited->commonTrans.autofill, "Common Properties for Transformations", "AutoFill", commonTrans.autofill, keyFile); // Rotation @@ -6767,6 +6771,8 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo // Distortion saveToKeyfile(!pedited || pedited->distortion.amount, "Distortion", "Amount", distortion.amount, keyFile); + saveToKeyfile(!pedited || pedited->distortion.focal_length, "Distortion", "FocalLength", distortion.focal_length, keyFile); + saveToKeyfile(!pedited || pedited->distortion.defish, "Distortion", "Defish", distortion.defish, keyFile); // Lens profile saveToKeyfile(!pedited || pedited->lensProf.lcMode, "LensProfile", "LcMode", lensProf.getMethodString(lensProf.lcMode), keyFile); @@ -8973,11 +8979,18 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } else { commonTrans.method = "lin"; } + if (keyFile.has_key("Common Properties for Transformations", "Scale")) { + assignFromKeyfile(keyFile, "Common Properties for Transformations", "Scale", commonTrans.scale, pedited->commonTrans.scale); + } else { + commonTrans.scale = 1.0; + } assignFromKeyfile(keyFile, "Common Properties for Transformations", "AutoFill", commonTrans.autofill, pedited->commonTrans.autofill); } if (keyFile.has_group("Distortion")) { assignFromKeyfile(keyFile, "Distortion", "Amount", distortion.amount, pedited->distortion.amount); + assignFromKeyfile(keyFile, "Distortion", "Defish", distortion.defish, pedited->distortion.defish); + assignFromKeyfile(keyFile, "Distortion", "FocalLength", distortion.focal_length, pedited->distortion.focal_length); } if (keyFile.has_group("LensProfile")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 9ac023d17..117c8b3d6 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -929,9 +929,12 @@ struct CoarseTransformParams { struct CommonTransformParams { Glib::ustring method; bool autofill; + double scale; CommonTransformParams(); + double getScale() const; + bool operator ==(const CommonTransformParams& other) const; bool operator !=(const CommonTransformParams& other) const; }; @@ -952,7 +955,10 @@ struct RotateParams { * Parameters of the distortion correction */ struct DistortionParams { - double amount; + static constexpr double DEFAULT_FOCAL_LENGTH = 12; + double amount = 0.0; + bool defish = false; + double focal_length = DEFAULT_FOCAL_LENGTH; DistortionParams(); diff --git a/rtgui/addsetids.h b/rtgui/addsetids.h index d0d24fa76..2a123a9f7 100644 --- a/rtgui/addsetids.h +++ b/rtgui/addsetids.h @@ -20,6 +20,8 @@ enum { ADDSET_WB_GREEN, ADDSET_ROTATE_DEGREE, ADDSET_DIST_AMOUNT, + ADDSET_DIST_DEFISH, + ADDSET_DIST_FOCAL_LENGTH, ADDSET_PERSPECTIVE, ADDSET_PERSP_CAM_ANGLE, ADDSET_PERSP_CAM_FOCAL_LENGTH, @@ -116,6 +118,7 @@ enum { ADDSET_WA_EDGS, ADDSET_WA_SCALE, ADDSET_WA_GAMMA, + ADDSET_LENSGEOM_SCALE, ADDSET_RETI_STR, ADDSET_RETI_NEIGH, ADDSET_RETI_LIMD, diff --git a/rtgui/batchtoolpanelcoord.cc b/rtgui/batchtoolpanelcoord.cc index 83d541334..219054ca4 100644 --- a/rtgui/batchtoolpanelcoord.cc +++ b/rtgui/batchtoolpanelcoord.cc @@ -151,7 +151,7 @@ void BatchToolPanelCoordinator::initSession () colorappearance->setAdjusterBehavior (false, false, false, false, false, false, false, false, false, false, false, false, false, false, false); rotate->setAdjusterBehavior (false); resize->setAdjusterBehavior (false); - distortion->setAdjusterBehavior (false); + distortion->setAdjusterBehavior (false, false); perspective->setAdjusterBehavior (false, false, false, false, false, false, false); gradient->setAdjusterBehavior (false, false, false, false); pcvignette->setAdjusterBehavior (false, false, false); @@ -196,8 +196,19 @@ void BatchToolPanelCoordinator::initSession () colorappearance->setAdjusterBehavior (options.baBehav[ADDSET_CAT_DEGREE], options.baBehav[ADDSET_CAT_ADAPTSCENE], options.baBehav[ADDSET_CAT_ADAPTVIEWING], options.baBehav[ADDSET_CAT_BADPIX], options.baBehav[ADDSET_CAT_LIGHT], options.baBehav[ADDSET_CAT_CHROMA], options.baBehav[ADDSET_CAT_CONTRAST], options.baBehav[ADDSET_CAT_RSTPRO], options.baBehav[ADDSET_CAT_BRIGHT], options.baBehav[ADDSET_CAT_CONTRAST_Q], options.baBehav[ADDSET_CAT_CHROMA_S], options.baBehav[ADDSET_CAT_CHROMA_M], options.baBehav[ADDSET_CAT_HUE],options.baBehav[ADDSET_CAT_DEGREEOUT], options.baBehav[ADDSET_CAT_TEMPOUT] ); rotate->setAdjusterBehavior (options.baBehav[ADDSET_ROTATE_DEGREE]); resize->setAdjusterBehavior (options.baBehav[ADDSET_RESIZE_SCALE]); - distortion->setAdjusterBehavior (options.baBehav[ADDSET_DIST_AMOUNT]); - perspective->setAdjusterBehavior (options.baBehav[ADDSET_PERSPECTIVE], options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH], options.baBehav[ADDSET_PERSP_CAM_SHIFT], options.baBehav[ADDSET_PERSP_CAM_ANGLE], options.baBehav[ADDSET_PERSP_PROJ_ANGLE], options.baBehav[ADDSET_PERSP_PROJ_SHIFT], options.baBehav[ADDSET_PERSP_PROJ_ROTATE]); + distortion->setAdjusterBehavior ( + options.baBehav[ADDSET_DIST_AMOUNT], + options.baBehav[ADDSET_DIST_FOCAL_LENGTH] + ); + perspective->setAdjusterBehavior ( + options.baBehav[ADDSET_PERSPECTIVE], + options.baBehav[ADDSET_PERSP_CAM_FOCAL_LENGTH], + options.baBehav[ADDSET_PERSP_CAM_SHIFT], + options.baBehav[ADDSET_PERSP_CAM_ANGLE], + options.baBehav[ADDSET_PERSP_PROJ_ANGLE], + options.baBehav[ADDSET_PERSP_PROJ_SHIFT], + options.baBehav[ADDSET_PERSP_PROJ_ROTATE] + ); gradient->setAdjusterBehavior (options.baBehav[ADDSET_GRADIENT_DEGREE], options.baBehav[ADDSET_GRADIENT_FEATHER], options.baBehav[ADDSET_GRADIENT_STRENGTH], options.baBehav[ADDSET_GRADIENT_CENTER]); pcvignette->setAdjusterBehavior (options.baBehav[ADDSET_PCVIGNETTE_STRENGTH], options.baBehav[ADDSET_PCVIGNETTE_FEATHER], options.baBehav[ADDSET_PCVIGNETTE_ROUNDNESS]); cacorrection->setAdjusterBehavior (options.baBehav[ADDSET_CA]); diff --git a/rtgui/distortion.cc b/rtgui/distortion.cc index 083c2f03a..0f0144b58 100644 --- a/rtgui/distortion.cc +++ b/rtgui/distortion.cc @@ -22,7 +22,10 @@ #include "rtimage.h" +#include "eventmapper.h" + #include "../rtengine/procparams.h" +#include "../rtengine/refreshmap.h" using namespace rtengine; using namespace rtengine::procparams; @@ -31,6 +34,14 @@ const Glib::ustring Distortion::TOOL_NAME = "distortion"; Distortion::Distortion (): FoldableToolPanel(this, TOOL_NAME, M("TP_DISTORTION_LABEL")) { + auto mapper = ProcEventMapper::getInstance(); + EvDistortionDefish = mapper->newEvent(TRANSFORM, "HISTORY_MSG_DISTORTION_DEFISH"); + EvDistortionDefishVoid = mapper->newEvent(M_VOID, "HISTORY_MSG_DISTORTION_DEFISH"); + + EvDistortionDefishFocalLength = mapper->newEvent(TRANSFORM, "HISTORY_MSG_DISTORTION_DEFISH_FOCAL"); + EvDistortionDefishFocalLengthVoid = mapper->newEvent(M_VOID, "HISTORY_MSG_DISTORTION_DEFISH_FOCAL"); + + setCamBasedEventsActive(); rlistener = nullptr; autoDistor = Gtk::manage (new Gtk::Button (M("GENERAL_AUTO"))); @@ -47,11 +58,26 @@ Distortion::Distortion (): FoldableToolPanel(this, TOOL_NAME, M("TP_DISTORTION_L distor = Gtk::manage (new Adjuster (M("TP_DISTORTION_AMOUNT"), -0.5, 0.5, 0.001, 0, idistL, idistR)); distor->setAdjusterListener (this); - distor->setLogScale(2, 0); - distor->show(); pack_start (*distor); + + Gtk::Frame* defish_frame = Gtk::manage (new Gtk::Frame()); + defish_frame->set_label_align(0.025, 0.5); + Gtk::Box* defish_vbox = Gtk::manage (new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + defish = Gtk::manage(new Gtk::CheckButton(M("TP_DISTORTION_DEFISH"))); + defish->signal_toggled().connect(sigc::mem_fun(*this, &Distortion::defishChanged)); + defish->show(); + defish_frame->set_label_widget(*defish); + + focal_length = Gtk::manage (new Adjuster (M("TP_DISTORTION_FOCAL_LENGTH"), 0.5, 25, 0.01, DistortionParams::DEFAULT_FOCAL_LENGTH)); + focal_length->setAdjusterListener (this); + focal_length->show(); + focal_length->setEnabled(defish->get_active()); + defish_vbox->pack_start(*focal_length); + + defish_frame->add(*defish_vbox); + pack_start (*defish_frame); } void Distortion::read (const ProcParams* pp, const ParamsEdited* pedited) @@ -61,9 +87,13 @@ void Distortion::read (const ProcParams* pp, const ParamsEdited* pedited) if (pedited) { distor->setEditedState (pedited->distortion.amount ? Edited : UnEdited); + focal_length->setEditedState (pedited->distortion.focal_length != DistortionParams::DEFAULT_FOCAL_LENGTH ? Edited : UnEdited); } distor->setValue (pp->distortion.amount); + defish->set_active(pp->distortion.defish); + focal_length->setValue(pp->distortion.focal_length); + focal_length->setEnabled(defish->get_active()); enableListener (); } @@ -72,9 +102,13 @@ void Distortion::write (ProcParams* pp, ParamsEdited* pedited) { pp->distortion.amount = distor->getValue (); + pp->distortion.defish = defish->get_active (); + pp->distortion.focal_length = focal_length->getValue (); if (pedited) { pedited->distortion.amount = distor->getEditedState (); + pedited->distortion.focal_length = focal_length->getEditedState (); + pedited->distortion.defish = true; } } @@ -82,6 +116,7 @@ void Distortion::setDefaults (const ProcParams* defParams, const ParamsEdited* p { distor->setDefault (defParams->distortion.amount); + focal_length->setDefault (defParams->distortion.focal_length); if (pedited) { distor->setDefaultEditedState (pedited->distortion.amount ? Edited : UnEdited); @@ -93,7 +128,12 @@ void Distortion::setDefaults (const ProcParams* defParams, const ParamsEdited* p void Distortion::adjusterChanged(Adjuster* a, double newval) { if (listener) { - listener->panelChanged (EvDISTAmount, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); + if (a == focal_length) { + listener->panelChanged (*event_distortion_defish_focal_length, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(2), a->getValue())); + } + else if (a == distor) { + listener->panelChanged (EvDISTAmount, Glib::ustring::format (std::setw(4), std::fixed, std::setprecision(3), a->getValue())); + } } } @@ -120,14 +160,35 @@ void Distortion::idPressed () } } -void Distortion::setAdjusterBehavior (bool vadd) +void Distortion::defishChanged() { + if (listener) { + listener->panelChanged(EvDistortionDefish, defish->get_active() ? M("GENERAL_ENABLED") : M("GENERAL_DISABLED")); + focal_length->setEnabled(defish->get_active()); + } +} +void Distortion::setCamBasedEventsActive(bool active) +{ + if (active) { + event_distortion_defish = &EvDistortionDefish; + event_distortion_defish_focal_length = &EvDistortionDefishFocalLength; + } + else { + event_distortion_defish = &EvDistortionDefishVoid; + event_distortion_defish_focal_length = &EvDistortionDefishFocalLengthVoid; + } +} + +void Distortion::setAdjusterBehavior (bool vadd, bool focal_length_add) +{ distor->setAddMode(vadd); + focal_length->setAddMode(focal_length_add); } void Distortion::trimValues (rtengine::procparams::ProcParams* pp) { distor->trimValue(pp->distortion.amount); + focal_length->trimValue(pp->distortion.focal_length); } diff --git a/rtgui/distortion.h b/rtgui/distortion.h index 98044bacf..456331cb6 100644 --- a/rtgui/distortion.h +++ b/rtgui/distortion.h @@ -33,10 +33,20 @@ class Distortion final : protected: Gtk::Button* autoDistor; Adjuster* distor; + Adjuster* focal_length; sigc::connection idConn; LensGeomListener * rlistener; + Gtk::CheckButton* defish; public: + rtengine::ProcEvent EvDistortionDefish; + rtengine::ProcEvent EvDistortionDefishVoid; + rtengine::ProcEvent* event_distortion_defish; + + rtengine::ProcEvent EvDistortionDefishFocalLength; + rtengine::ProcEvent EvDistortionDefishFocalLengthVoid; + rtengine::ProcEvent* event_distortion_defish_focal_length; + static const Glib::ustring TOOL_NAME; Distortion (); @@ -47,11 +57,14 @@ public: void setBatchMode (bool batchMode) override; void adjusterChanged (Adjuster* a, double newval) override; - void setAdjusterBehavior (bool vadd); + void setAdjusterBehavior (bool vadd, bool focal_length_add); void trimValues (rtengine::procparams::ProcParams* pp) override; void idPressed (); void setLensGeomListener (LensGeomListener* l) { rlistener = l; } + void defishChanged (void); + + void setCamBasedEventsActive(bool active = true); }; diff --git a/rtgui/lensgeom.cc b/rtgui/lensgeom.cc index 0064ecee3..2f4306cd8 100644 --- a/rtgui/lensgeom.cc +++ b/rtgui/lensgeom.cc @@ -18,6 +18,8 @@ */ #include "lensgeom.h" +#include + #include "eventmapper.h" #include "guiutils.h" #include "rtimage.h" @@ -31,8 +33,8 @@ const Glib::ustring LensGeometry::TOOL_NAME = "lensgeom"; LensGeometry::LensGeometry () : FoldableToolPanel(this, TOOL_NAME, M("TP_LENSGEOM_LABEL")), rlistener(nullptr), lastFill(false) { - auto m = ProcEventMapper::getInstance(); + EvTransScale = m->newEvent(TRANSFORM, "HISTORY_MSG_TRANS_SCALE"); EvTransMethod = m->newEvent(TRANSFORM, "HISTORY_MSG_TRANS_METHOD"); Gtk::Box* hb1 = Gtk::manage (new Gtk::Box ()); @@ -44,6 +46,11 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, TOOL_NAME, M("TP_LENSGEO hb1->pack_end (*method, Gtk::PACK_EXPAND_WIDGET, 4); pack_start( *hb1, Gtk::PACK_SHRINK, 4); + scale= Gtk::manage (new Adjuster (M("TP_LENSGEOM_SCALE"), 0.1, 10, 0.01, 1)); + scale->setAdjusterListener (this); + scale->setLogScale(300, 0.1); + pack_start (*scale); + fill = Gtk::manage (new Gtk::CheckButton (M("TP_LENSGEOM_FILL"))); pack_start (*fill); @@ -57,6 +64,7 @@ LensGeometry::LensGeometry () : FoldableToolPanel(this, TOOL_NAME, M("TP_LENSGEO fillConn = fill->signal_toggled().connect(sigc::mem_fun(*this, &LensGeometry::fillPressed)); fill->set_active (true); + scale->setEnabled(!fill->get_active()); show_all (); } @@ -78,6 +86,7 @@ void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited) } fill->set_inconsistent (!pedited->commonTrans.autofill); + scale->setEditedState (pedited->commonTrans.scale ? Edited : UnEdited); } fillConn.block (true); @@ -85,9 +94,12 @@ void LensGeometry::read (const ProcParams* pp, const ParamsEdited* pedited) fillConn.block (false); autoCrop->set_sensitive (!pp->commonTrans.autofill); + scale->setValue (pp->commonTrans.scale); + lastFill = pp->commonTrans.autofill; method->block (false); + scale->setEnabled(!fill->get_active()); enableListener (); } @@ -97,11 +109,13 @@ void LensGeometry::write (ProcParams* pp, ParamsEdited* pedited) if( currentRow >= 0 && method->get_active_text() != M("GENERAL_UNCHANGED")) { pp->commonTrans.method = currentRow == 0 ? "log" : "lin"; } - pp->commonTrans.autofill = fill->get_active (); + pp->commonTrans.autofill = fill->get_active (); + pp->commonTrans.scale = scale->getValue (); if (pedited) { pedited->commonTrans.method = method->get_active_text() != M("GENERAL_UNCHANGED"); - pedited->commonTrans.autofill = !fill->get_inconsistent(); + pedited->commonTrans.autofill = !fill->get_inconsistent(); + pedited->commonTrans.scale = scale->getEditedState(); } } @@ -113,6 +127,21 @@ void LensGeometry::autoCropPressed () } } +void LensGeometry::adjusterChanged(Adjuster *a, double newval) +{ + if (listener) { + if (a == scale) { + listener->panelChanged (EvTransScale, + Glib::ustring::format(scale->getValue())); + } + else { + if (settings->verbose) { + std::cout << "Unknown adjuster given in LensGeometry::adjusterChanged, file " << __FILE__ << " line " << __LINE__ << std::endl; + } + } + } +} + void LensGeometry::fillPressed () { @@ -138,6 +167,7 @@ void LensGeometry::fillPressed () listener->panelChanged (EvTransAutoFill, M("GENERAL_DISABLED")); } } + scale->setEnabled(!fill->get_active()); } void LensGeometry::methodChanged () @@ -153,5 +183,6 @@ void LensGeometry::setBatchMode (bool batchMode) ToolPanel::setBatchMode (batchMode); removeIfThere (this, autoCrop); + scale->showEditedCB (); } diff --git a/rtgui/lensgeom.h b/rtgui/lensgeom.h index fa260e177..a84cfe84d 100644 --- a/rtgui/lensgeom.h +++ b/rtgui/lensgeom.h @@ -22,21 +22,25 @@ #include "lensgeomlistener.h" #include "toolpanel.h" +#include "adjuster.h" class LensGeometry final : public ToolParamBlock, - public FoldableToolPanel + public FoldableToolPanel, + public AdjusterListener { protected: MyComboBoxText* method; Gtk::Button* autoCrop; LensGeomListener* rlistener; + Adjuster* scale; Gtk::CheckButton* fill; bool lastFill; sigc::connection fillConn; rtengine::ProcEvent EvTransMethod; + rtengine::ProcEvent EvTransScale; public: static const Glib::ustring TOOL_NAME; @@ -55,6 +59,8 @@ public: rlistener = l; } + void adjusterChanged (Adjuster* a, double newval) override; + private: IdleRegister idle_register; }; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 7ca77a794..27f36f46a 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -345,8 +345,11 @@ void ParamsEdited::set(bool v) coarse.vflip = v; commonTrans.method = v; commonTrans.autofill = v; + commonTrans.scale = v; rotate.degree = v; distortion.amount = v; + distortion.defish = v; + distortion.focal_length = v; lensProf.lcMode = v; lensProf.lcpFile = v; lensProf.useDist = v; @@ -1078,9 +1081,12 @@ void ParamsEdited::initFrom(const std::vector& coarse.hflip = coarse.hflip && p.coarse.hflip == other.coarse.hflip; coarse.vflip = coarse.vflip && p.coarse.vflip == other.coarse.vflip; commonTrans.method = commonTrans.method && p.commonTrans.method == other.commonTrans.method; + commonTrans.scale = commonTrans.scale && p.commonTrans.scale == other.commonTrans.scale; commonTrans.autofill = commonTrans.autofill && p.commonTrans.autofill == other.commonTrans.autofill; rotate.degree = rotate.degree && p.rotate.degree == other.rotate.degree; distortion.amount = distortion.amount && p.distortion.amount == other.distortion.amount; + distortion.defish = distortion.defish && p.distortion.defish == other.distortion.defish; + distortion.focal_length = distortion.focal_length && p.distortion.focal_length == other.distortion.focal_length; lensProf.lcMode = lensProf.lcMode && p.lensProf.lcMode == other.lensProf.lcMode; lensProf.lcpFile = lensProf.lcpFile && p.lensProf.lcpFile == other.lensProf.lcpFile; lensProf.useDist = lensProf.useDist && p.lensProf.useDist == other.lensProf.useDist; @@ -3442,6 +3448,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.commonTrans.method = mods.commonTrans.method; } + if (commonTrans.scale) { + toEdit.commonTrans.scale = dontforceSet && options.baBehav[ADDSET_LENSGEOM_SCALE] ? toEdit.commonTrans.scale + mods.commonTrans.scale : mods.commonTrans.scale; + } + if (commonTrans.autofill) { toEdit.commonTrans.autofill = mods.commonTrans.autofill; } @@ -3454,6 +3464,14 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.distortion.amount = dontforceSet && options.baBehav[ADDSET_DIST_AMOUNT] ? toEdit.distortion.amount + mods.distortion.amount : mods.distortion.amount; } + if (distortion.defish) { + toEdit.distortion.defish = mods.distortion.defish; + } + + if (distortion.focal_length) { + toEdit.distortion.focal_length = dontforceSet && options.baBehav[ADDSET_DIST_FOCAL_LENGTH] ? toEdit.distortion.focal_length + mods.distortion.focal_length : mods.distortion.focal_length; + } + if (lensProf.lcMode) { toEdit.lensProf.lcMode = mods.lensProf.lcMode; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 0481009e8..0293aec69 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -397,6 +397,7 @@ struct CoarseTransformParamsEdited { struct CommonTransformParamsEdited { bool method; + bool scale; bool autofill; }; @@ -406,6 +407,8 @@ struct RotateParamsEdited { struct DistortionParamsEdited { bool amount; + bool defish; + bool focal_length; }; class LocallabParamsEdited { diff --git a/rtgui/perspective.cc b/rtgui/perspective.cc index e46598912..55c100e12 100644 --- a/rtgui/perspective.cc +++ b/rtgui/perspective.cc @@ -619,7 +619,15 @@ void PerspCorrection::methodChanged (void) } -void PerspCorrection::setAdjusterBehavior (bool badd, bool camera_focal_length_add, bool camera_shift_add, bool camera_angle_add, bool projection_angle_add, bool projection_shift_add, bool projection_rotate_add) +void PerspCorrection::setAdjusterBehavior ( + bool badd, + bool camera_focal_length_add, + bool camera_shift_add, + bool camera_angle_add, + bool projection_angle_add, + bool projection_shift_add, + bool projection_rotate_add +) { horiz->setAddMode(badd); diff --git a/rtgui/perspective.h b/rtgui/perspective.h index 6ca2381e3..5f13cf683 100644 --- a/rtgui/perspective.h +++ b/rtgui/perspective.h @@ -121,7 +121,13 @@ public: void linesEraseButtonPressed (void); void methodChanged (void); void requestApplyControlLines(void); - void setAdjusterBehavior (bool badd, bool camera_focal_length_add, bool camera_shift_add, bool camera_angle_add, bool projection_angle_add, bool projection_shift_add, bool projection_rotate_add); + void setAdjusterBehavior (bool badd, + bool camera_focal_length_add, + bool camera_shift_add, + bool camera_angle_add, + bool projection_angle_add, + bool projection_shift_add, + bool projection_rotate_add); void setControlLineEditMode(bool active); void setEditProvider (EditDataProvider* provider) override; void setLensGeomListener (LensGeomListener* listener) diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index d102a2672..6c9756051 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -364,10 +364,15 @@ Gtk::Widget* Preferences::getBatchProcPanel() mi->set_value(behavColumns.label, M("TP_RESIZE_LABEL")); appendBehavList(mi, M("TP_RESIZE_SCALE"), ADDSET_RESIZE_SCALE, true); + mi = behModel->append(); + mi->set_value(behavColumns.label, M("TP_LENSGEOM_SCALE")); + appendBehavList(mi, M("TP_LENSGEOM_SCALE"), ADDSET_LENSGEOM_SCALE, true); mi = behModel->append(); mi->set_value(behavColumns.label, M("TP_DISTORTION_LABEL")); appendBehavList(mi, M("TP_DISTORTION_AMOUNT"), ADDSET_DIST_AMOUNT, false); + appendBehavList(mi, M("TP_DISTORTION_DEFISH"), ADDSET_DIST_DEFISH, false); + appendBehavList(mi, M("TP_DISTORTION_FOCAL_LENGTH"), ADDSET_DIST_FOCAL_LENGTH, false); mi = behModel->append(); mi->set_value(behavColumns.label, M("TP_PERSPECTIVE_LABEL"));