diff --git a/rtengine/PF_correct_RT.cc b/rtengine/PF_correct_RT.cc new file mode 100644 index 000000000..c62e91a24 --- /dev/null +++ b/rtengine/PF_correct_RT.cc @@ -0,0 +1,136 @@ +//////////////////////////////////////////////////////////////// +// +// Chromatic Aberration Auto-correction +// +// copyright (c) 2008-2010 Emil Martinec +// +// +// code dated: November 24, 2010 +// +// PF_correct_RT.cc 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. +// +// This program 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 this program. If not, see . +// +//////////////////////////////////////////////////////////////// +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +//#include +//#include +//#include +#include +//#include +#include + +#ifdef _OPENMP +#include +#endif + +#define SQR(x) ((x)*(x)) + +namespace rtengine { + +void ImProcFunctions::PF_correct_RT(LabImage * src, LabImage * dst, double radius, int thresh, bool edges) { + + float threshsqr = SQR(thresh); + int halfwin = ceil(2*radius)+1; + +#define SQR(x) ((x)*(x)) + + // local variables + int width=src->W, height=src->H; + //temporary array to store simple interpolation of G + int (*fringe); + fringe = (int (*)) calloc ((height)*(width), sizeof *fringe); + + LabImage * tmp1; + tmp1 = new LabImage(width, height); + +#ifdef _OPENMP +#pragma omp parallel +#endif + { + AlignedBuffer* buffer = new AlignedBuffer (MAX(src->W,src->H)); + gaussHorizontal (src->a, tmp1->a, buffer, src->W, src->H, radius, multiThread); + gaussHorizontal (src->b, tmp1->b, buffer, src->W, src->H, radius, multiThread); + gaussVertical (tmp1->a, tmp1->a, buffer, src->W, src->H, radius, multiThread); + gaussVertical (tmp1->b, tmp1->b, buffer, src->W, src->H, radius, multiThread); + + gaussHorizontal (src->L, tmp1->L, buffer, src->W, src->H, radius, multiThread); + gaussVertical (tmp1->L, tmp1->L, buffer, src->W, src->H, radius, multiThread); + + delete buffer; + } + +//#ifdef _OPENMP +//#pragma omp parallel for +//#endif + float chromave=0; + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + float chroma = SQR(src->a[i][j]-tmp1->a[i][j])+SQR(src->b[i][j]-tmp1->b[i][j]); + chromave += chroma; + fringe[i*width+j]=chroma; + } + } + chromave /= (height*width); + +#ifdef _OPENMP +#pragma omp parallel for +#endif + + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + tmp1->a[i][j] = src->a[i][j]; + tmp1->b[i][j] = src->b[i][j]; + //test for pixel darker than some fraction of neighborhood ave, and near an edge + if (100*tmp1->L[i][j]>thresh*src->L[i][j] && 100*abs(tmp1->L[i][j]-src->L[i][j])>0.1*(tmp1->L[i][j]+src->L[i][j])) { + float atot=0; + float btot=0; + float norm=0; + float wt; + for (int i1=MAX(0,i-halfwin+1); i1a[i1][j1]; + btot += wt*src->b[i1][j1]; + norm += wt; + } + tmp1->a[i][j] = (int)(atot/norm); + tmp1->b[i][j] = (int)(btot/norm); + }//end of ab channel averaging + } + } + +#ifdef _OPENMP +#pragma omp parallel for +#endif + + for(int i = 0; i < height; i++ ) { + for(int j = 0; j < width; j++) { + dst->L[i][j] = src->L[i][j]; + dst->a[i][j] = tmp1->a[i][j]; + dst->b[i][j] = tmp1->b[i][j]; + } + } + + delete tmp1; + free(fringe); + +//#undef SQR + +} + +} + diff --git a/rtgui/defringe.cc b/rtgui/defringe.cc new file mode 100644 index 000000000..2abea2a6c --- /dev/null +++ b/rtgui/defringe.cc @@ -0,0 +1,150 @@ +/* + * 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 +#include +#include + +using namespace rtengine; +using namespace rtengine::procparams; + +Defringe::Defringe () : ToolPanel () { + + enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED"))); + enabled->set_active (false); + enabled->show (); + pack_start (*enabled); + + Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator()); + hsep1->show (); + pack_start (*hsep1); + + enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Defringe::enabledChanged) ); + //edgConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Defringe::edgeChanged) ); + + radius = Gtk::manage (new Adjuster (M("TP_DEFRINGE_RADIUS"), 0.5, 5.0, 0.1, 2.0)); + threshold = Gtk::manage (new Adjuster (M("TP_DEFRINGE_THRESHOLD"), 0, 100, 1, 25)); + radius->setAdjusterListener (this); + threshold->setAdjusterListener (this); + radius->show(); + threshold->show(); + + pack_start (*radius); + pack_start (*threshold); +} + +void Defringe::read (const ProcParams* pp, const ParamsEdited* pedited) { + + disableListener (); + + if (pedited) { + radius->setEditedState (pedited->defringe.radius ? Edited : UnEdited); + threshold->setEditedState (pedited->defringe.threshold ? Edited : UnEdited); + enabled->set_inconsistent (!pedited->defringe.enabled); + } + + enaConn.block (true); + enabled->set_active (pp->defringe.enabled); + enaConn.block (false); + + lastEnabled = pp->defringe.enabled; + + radius->setValue (pp->defringe.radius); + threshold->setValue (pp->defringe.threshold); + + enableListener (); +} + +void Defringe::write (ProcParams* pp, ParamsEdited* pedited) { + + pp->defringe.radius = radius->getValue (); + pp->defringe.threshold = (int)threshold->getValue (); + pp->defringe.enabled = enabled->get_active(); + + if (pedited) { + pedited->defringe.radius = radius->getEditedState (); + pedited->defringe.threshold = threshold->getEditedState (); + pedited->defringe.enabled = !enabled->get_inconsistent(); + } +} + +void Defringe::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { + + radius->setDefault (defParams->defringe.radius); + threshold->setDefault (defParams->defringe.threshold); + + if (pedited) { + radius->setDefaultEditedState (pedited->defringe.radius ? Edited : UnEdited); + threshold->setDefaultEditedState (pedited->defringe.threshold ? Edited : UnEdited); + } + else { + radius->setDefaultEditedState (Irrelevant); + threshold->setDefaultEditedState (Irrelevant); + } +} + +void Defringe::adjusterChanged (Adjuster* a, double newval) { + + if (listener && enabled->get_active()) { + + if (a==radius) + listener->panelChanged (EvLDNRadius, Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue())); + else if (a==threshold) + listener->panelChanged (EvLDNEdgeTolerance, Glib::ustring::format ((int)a->getValue())); + } +} + +void Defringe::enabledChanged () { + + if (batchMode) { + if (enabled->get_inconsistent()) { + enabled->set_inconsistent (false); + enaConn.block (true); + enabled->set_active (false); + enaConn.block (false); + } + else if (lastEnabled) + enabled->set_inconsistent (true); + + lastEnabled = enabled->get_active (); + } + + if (listener) { + if (enabled->get_active ()) + listener->panelChanged (EvLDNEnabled, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvLDNEnabled, M("GENERAL_DISABLED")); + } +} + +void Defringe::setBatchMode (bool batchMode) { + + ToolPanel::setBatchMode (batchMode); + radius->showEditedCB (); + threshold->showEditedCB (); +} + +/*void Defringe::setAdjusterBehavior (bool bthresholdtoladd) { + + if (!thresholdtolAdd && bthresholdtoladd) + threshold->setLimits (-10000, 10000, 100, 0); + else if (thresholdtolAdd && !bthresholdtoladd) + threshold->setLimits (100, 10000, 100, 1000); + + thresholdtolAdd = bthresholdtoladd; +}*/ diff --git a/rtgui/defringe.h b/rtgui/defringe.h new file mode 100644 index 000000000..4d41d8bc6 --- /dev/null +++ b/rtgui/defringe.h @@ -0,0 +1,52 @@ +/* + * 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 _DEFRINGE_H_ +#define _DEFRINGE_H_ + +#include +#include +#include + +class Defringe : public Gtk::VBox, public AdjusterListener, public ToolPanel { + + protected: + Adjuster* radius; + Adjuster* threshold; + Gtk::CheckButton* enabled; + bool lastEnabled; + sigc::connection enaConn; + bool edges; + bool thresholdtolAdd; + + public: + + Defringe (); + + 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 setAdjusterBehavior (bool bthresholdtoladd); +}; + +#endif