Added wavelet equalizer module

This commit is contained in:
Ilia Popov 2010-06-30 23:28:45 +02:00
parent e37b23ae8b
commit e0c25b4db6
22 changed files with 1632 additions and 787 deletions

View File

@ -525,6 +525,9 @@ TP_CROP_X;x
TP_CROP_Y;y TP_CROP_Y;y
TP_DISTORTION_AMOUNT;Amount TP_DISTORTION_AMOUNT;Amount
TP_DISTORTION_LABEL;Distortion TP_DISTORTION_LABEL;Distortion
TP_EQUALIZER_LABEL;Wavelet equalizer
TP_EQUALIZER_FINEST;finest
TP_EQUALIZER_LARGEST;coarsest
TP_EXPOSURE_AUTOLEVELS;Auto Levels TP_EXPOSURE_AUTOLEVELS;Auto Levels
TP_EXPOSURE_BLACKLEVEL;Black TP_EXPOSURE_BLACKLEVEL;Black
TP_EXPOSURE_BRIGHTNESS;Brightness TP_EXPOSURE_BRIGHTNESS;Brightness

View File

@ -527,6 +527,9 @@ TP_CROP_X;x
TP_CROP_Y;y TP_CROP_Y;y
TP_DISTORTION_AMOUNT;Amount TP_DISTORTION_AMOUNT;Amount
TP_DISTORTION_LABEL;Distortion TP_DISTORTION_LABEL;Distortion
TP_EQUALIZER_LABEL;Wavelet equalizer
TP_EQUALIZER_FINEST;finest
TP_EQUALIZER_LARGEST;coarsest
TP_EXPOSURE_AUTOLEVELS;Auto Levels TP_EXPOSURE_AUTOLEVELS;Auto Levels
TP_EXPOSURE_BLACKLEVEL;Black TP_EXPOSURE_BLACKLEVEL;Black
TP_EXPOSURE_BRIGHTNESS;Brightness TP_EXPOSURE_BRIGHTNESS;Brightness

View File

@ -11,7 +11,8 @@ set (RTENGINESOURCEFILES colortemp.cc curves.cc dcraw.cc iccstore.cc
loadinitial.cc procparams.cc rawimagesource.cc shmap.cc simpleprocess.cc refreshmap.cc loadinitial.cc procparams.cc rawimagesource.cc shmap.cc simpleprocess.cc refreshmap.cc
stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc
processingjob.cc rtthumbnail.cc utils.cc labimage.cc processingjob.cc rtthumbnail.cc utils.cc labimage.cc
iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc) iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc
wavelet_dec.cc ipequalizer.cc)
add_library (rtengine ${RTENGINESOURCEFILES}) add_library (rtengine ${RTENGINESOURCEFILES})
#It may be nice to store library version too #It may be nice to store library version too

View File

@ -89,6 +89,7 @@ class ImProcFunctions {
void lab2rgb (LabImage* lab, Image8* image); void lab2rgb (LabImage* lab, Image8* image);
void resize (Image16* src, Image16* dst); void resize (Image16* src, Image16* dst);
void deconvsharpening(LabImage* lab, unsigned short** buffer); void deconvsharpening(LabImage* lab, unsigned short** buffer);
void waveletEqualizer(Image16 * image, int fw, int fh, const EqualizerParams & params);
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile); Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile); Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, Glib::ustring profile);

40
rtengine/ipequalizer.cc Normal file
View File

@ -0,0 +1,40 @@
/*
* This file is part of RawTherapee.
*
* 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 <http://www.gnu.org/licenses/>.
*
* 2010 Ilya Popov <ilia_popov@rambler.ru>
*/
#include <rtengine.h>
#include <improcfun.h>
#include <wavelet_dec.h>
namespace rtengine {
void ImProcFunctions :: waveletEqualizer(Image16 * image, int fw, int fh, const EqualizerParams & params) {
wavelet_decomposition r(image->r, fw, fh);
r.reconstruct(image->r, params.c);
wavelet_decomposition g(image->g, fw, fh);
g.reconstruct(image->g, params.c);
wavelet_decomposition b(image->b, fw, fh);
b.reconstruct(image->b, params.c);
}
}

View File

@ -21,7 +21,7 @@
#include <rtengine.h> #include <rtengine.h>
#define NUMOFEVENTS 84 #define NUMOFEVENTS 86
namespace rtengine { namespace rtengine {
@ -109,7 +109,9 @@ enum ProcEvent {
EvResizeEnabled=80, EvResizeEnabled=80,
EvProfileChangeNotification=81, EvProfileChangeNotification=81,
EvSHHighQuality=82, EvSHHighQuality=82,
EvPerspCorr=83 EvPerspCorr=83,
EvEqualizer=84,
EvEqlEnabled=85
}; };
} }
#endif #endif

View File

@ -158,6 +158,12 @@ void ProcParams::setDefaults () {
icm.working = "sRGB"; icm.working = "sRGB";
icm.output = "sRGB"; icm.output = "sRGB";
equalizer.enabled = false;
for(int i = 0; i < 8; i ++)
{
equalizer.c[i] = 0;
}
exif.clear (); exif.clear ();
iptc.clear (); iptc.clear ();
@ -304,6 +310,15 @@ int ProcParams::save (Glib::ustring fname) const {
keyFile.set_string ("Color Management", "WorkingProfile", icm.working); keyFile.set_string ("Color Management", "WorkingProfile", icm.working);
keyFile.set_string ("Color Management", "OutputProfile", icm.output); keyFile.set_string ("Color Management", "OutputProfile", icm.output);
// save wavelet equalizer parameters
keyFile.set_boolean ("Equalizer", "Enabled", equalizer.enabled);
for(int i = 0; i < 8; i++)
{
std::stringstream ss;
ss << "C" << i;
keyFile.set_integer("Equalizer", ss.str(), equalizer.c[i]);
}
// save exif change list // save exif change list
for (int i=0; i<exif.size(); i++) for (int i=0; i<exif.size(); i++)
keyFile.set_string ("Exif", exif[i].field, exif[i].value); keyFile.set_string ("Exif", exif[i].field, exif[i].value);
@ -530,6 +545,17 @@ if (keyFile.has_group ("Color Management")) {
if (keyFile.has_key ("Color Management", "OutputProfile")) icm.output = keyFile.get_string ("Color Management", "OutputProfile"); if (keyFile.has_key ("Color Management", "OutputProfile")) icm.output = keyFile.get_string ("Color Management", "OutputProfile");
} }
// load wavelet equalizer parameters
if (keyFile.has_group ("Equalizer")) {
if (keyFile.has_key ("Equalizer", "Enabled")) equalizer.enabled = keyFile.get_boolean ("Equalizer", "Enabled");
for(int i = 0; i < 8; i ++)
{
std::stringstream ss;
ss << "C" << i;
if(keyFile.has_key ("Equalizer", ss.str())) equalizer.c[i] = keyFile.get_integer ("Equalizer", ss.str());
}
}
// load exif change settings // load exif change settings
if (keyFile.has_group ("Exif")) { if (keyFile.has_group ("Exif")) {
std::vector<Glib::ustring> keys = keyFile.get_keys ("Exif"); std::vector<Glib::ustring> keys = keyFile.get_keys ("Exif");
@ -562,6 +588,17 @@ if (keyFile.has_group ("IPTC")) {
} }
} }
bool operator==(const EqualizerParams & a, const EqualizerParams & b) {
if(a.enabled != b.enabled)
return false;
for(int i = 0; i < 8; i++) {
if(a.c[i] != b.c[i])
return false;
}
return true;
}
bool operator==(const ExifPair& a, const ExifPair& b) { bool operator==(const ExifPair& a, const ExifPair& b) {
return a.field == b.field && a.value == b.value; return a.field == b.field && a.value == b.value;
@ -660,6 +697,7 @@ bool ProcParams::operator== (const ProcParams& other) {
&& icm.gammaOnInput == other.icm.gammaOnInput && icm.gammaOnInput == other.icm.gammaOnInput
&& icm.working == other.icm.working && icm.working == other.icm.working
&& icm.output == other.icm.output && icm.output == other.icm.output
&& equalizer == other.equalizer
&& exif==other.exif && exif==other.exif
&& iptc==other.iptc; && iptc==other.iptc;
} }

View File

@ -302,6 +302,16 @@ class IPTCPair {
std::vector<Glib::ustring> values; std::vector<Glib::ustring> values;
}; };
/**
* Wavelet equalizer params
*/
class EqualizerParams {
public:
bool enabled;
int c[8];
};
/** /**
* This class holds all the processing parameters applied on the images * This class holds all the processing parameters applied on the images
*/ */
@ -329,6 +339,7 @@ class ProcParams {
HRecParams hlrecovery; ///< Highlight recovery parameters HRecParams hlrecovery; ///< Highlight recovery parameters
ResizeParams resize; ///< Resize parameters ResizeParams resize; ///< Resize parameters
ColorManagementParams icm; ///< profiles/color spaces used during the image processing ColorManagementParams icm; ///< profiles/color spaces used during the image processing
EqualizerParams equalizer; ///< wavelet equalizer parameters
std::vector<ExifPair> exif; ///< List of modifications appplied on the exif tags of the input image std::vector<ExifPair> exif; ///< List of modifications appplied on the exif tags of the input image
std::vector<IPTCPair> iptc; ///< The IPTC tags and values to be saved to the output image std::vector<IPTCPair> iptc; ///< The IPTC tags and values to be saved to the output image
int version; ///< Version of the file from which the parameters have been read int version; ///< Version of the file from which the parameters have been read

View File

@ -102,6 +102,7 @@ ALL, // EvResizeHeight
ALL, // EvResizeEnabled ALL, // EvResizeEnabled
ALL, // EvProfileChangeNotification ALL, // EvProfileChangeNotification
RETINEX, // EvShrHighQuality RETINEX, // EvShrHighQuality
TRANSFORM // EvPerspCorr TRANSFORM, // EvPerspCorr
ALL // ????? EvEqualizer
}; };

View File

@ -25,6 +25,8 @@
#include <processingjob.h> #include <processingjob.h>
#include <glibmm.h> #include <glibmm.h>
#include <iostream>
#undef THREAD_PRIORITY_NORMAL #undef THREAD_PRIORITY_NORMAL
namespace rtengine { namespace rtengine {
@ -101,6 +103,10 @@ IImage16* processImage (ProcessingJob* pjob, int& errorCode, ProgressListener* p
baseImg = trImg; baseImg = trImg;
} }
if (params.equalizer.enabled) {
ipf.waveletEqualizer (baseImg, fw, fh, params.equalizer);
}
// update blurmap // update blurmap
int** buffer = new int*[fh]; int** buffer = new int*[fh];
for (int i=0; i<fh; i++) for (int i=0; i<fh; i++)

170
rtengine/wavelet.h Normal file
View File

@ -0,0 +1,170 @@
/*
* This file is part of RawTherapee.
*
* 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 <http://www.gnu.org/licenses/>.
*
* 2010 Ilya Popov <ilia_popov@rambler.ru>
*/
#ifndef WAVELET_H_INCLUDED
#define WAVELET_H_INCLUDED
template<class T>
void dwt_haar(T * data, size_t pitch, T * buffer, size_t n)
{
size_t n2a = (n + 1) / 2;
size_t n2 = n/2;
for(size_t i = 0, j = 0; i < n2; i++, j += 2 * pitch)
{
T a = data[j];
T b = data[j + pitch];
buffer[i] = (a + b) / 2;
buffer[n2a + i] = (a - b);
}
if(n2 < n2a)
{
buffer[n2] = data[pitch * (n-1)];
}
for(size_t k = 0, q = 0; k < n; k++, q += pitch)
{
data[q] = buffer[k];
}
}
template<class T>
void idwt_haar(T * data, size_t pitch, T * buffer, size_t n, int alpha)
{
size_t n2a = (n + 1) / 2;
size_t n2 = n/2;
for(size_t i = 0, j = 0; i < n2; i++, j += 2)
{
T p = data[i * pitch];
T q = (alpha * data[(n2a + i)*pitch]) / 1024;
buffer[j] = p + q / 2;
buffer[j + 1] = p - q / 2;
}
if(n2 < n2a)
{
buffer[n-1] = data[pitch * n2];
}
for(size_t k = 0, q = 0; k < n; k++, q += pitch)
{
data[q] = buffer[k];
}
}
// buffer must be of length (n + 4)
template<class T>
void dwt_53(T * data, size_t pitch, T * buffer, size_t n)
{
size_t n2 = n/2;
size_t n2a = (n + 1) / 2;
T * tmp = buffer + 2;
// copy data
for(size_t i = 0, j = 0; i < n; i++, j += pitch)
{
tmp[i] = data[j];
}
// extend mirror-like
tmp[-1] = tmp[1];
tmp[-2] = tmp[2];
tmp[n] = tmp[n-2];
tmp[n+1] = tmp[n-3];
// calculate coefficients
for(int j = -1; j < (int)n + 1; j += 2)
{
tmp[j] = tmp[j] - (tmp[j-1] + tmp[j+1]) / 2;
}
for(int i = 0; i < (int)n; i += 2)
{
tmp[i] = tmp[i] + (tmp[i-1] + tmp[i+1] + 2) / 4;
}
// copy with reordering
for(size_t i = 0, j = 0; i < n; i+=2, j += pitch)
{
data[j] = tmp[i];
}
for(size_t i = 1, j = n2a*pitch; i < n; i+=2, j += pitch)
{
data[j] = tmp[i];
}
}
template<class T>
void idwt_53(T * data, size_t pitch, T * buffer, size_t n, int alpha)
{
size_t n2 = n/2;
size_t n2a = (n + 1) / 2;
T * tmp = buffer + 2;
// copy with reordering
for(size_t i = 0, j = 0; i < n; i+=2, j += pitch)
{
tmp[i] = data[j];
}
for(size_t i = 1, j = n2a*pitch; i < n; i+=2, j += pitch)
{
tmp[i] = (alpha * data[j]) / 1024;
}
// extend mirror-like
tmp[-1] = tmp[1];
tmp[-2] = tmp[2];
tmp[n] = tmp[n-2];
tmp[n+1] = tmp[n-3];
// calculate coefficients
for(int i = 0; i < (int)n + 1; i += 2)
{
tmp[i] = tmp[i] - (tmp[i-1] + tmp[i+1] + 2) / 4;
}
for(int j = 1; j < (int)n; j += 2)
{
tmp[j] = tmp[j] + (tmp[j-1] + tmp[j+1]) / 2;
}
// copy data
for(size_t i = 0, j = 0; i < n; i++, j += pitch)
{
data[j] = tmp[i];
}
}
#endif

62
rtengine/wavelet_dec.cc Normal file
View File

@ -0,0 +1,62 @@
/*
* This file is part of RawTherapee.
*
* 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 <http://www.gnu.org/licenses/>.
*
* 2010 Ilya Popov <ilia_popov@rambler.ru>
*/
#include "wavelet_dec.h"
namespace rtengine
{
wavelet_decomposition::wavelet_decomposition(unsigned short ** src, size_t w, size_t h)
: nlevels(0), m_w(w), m_h(h), m_w1(0), m_h1(0)
{
m_w1 = w;
m_h1 = h;
m_c[0] = new wavelet_level<internal_type>(src, m_w1, m_h1);
nlevels = 1;
while(nlevels < maxlevels)
{
m_c[nlevels] = new wavelet_level<internal_type>(m_c[nlevels - 1]->lowfreq(), m_c[nlevels-1]->lfw(), m_c[nlevels-1]->lfh());
nlevels ++;
}
}
wavelet_decomposition::~wavelet_decomposition()
{
for(int i = 0; i < nlevels; i++)
{
delete m_c[i];
}
}
void wavelet_decomposition::reconstruct(unsigned short ** dst, const int * c)
{
for(int level = nlevels - 1; level > 0; level--)
{
int alpha = 1024 + 10 * c[level];
m_c[level]->reconstruct(m_c[level-1]->lowfreq(), alpha);
}
int alpha = 1024 + 10 * c[0];
m_c[0]->reconstruct(dst, alpha, wavelet_level<internal_type>::CLIP);
}
};

53
rtengine/wavelet_dec.h Normal file
View File

@ -0,0 +1,53 @@
/*
* This file is part of RawTherapee.
*
* 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 <http://www.gnu.org/licenses/>.
*
* 2010 Ilya Popov <ilia_popov@rambler.ru>
*/
#ifndef WAVELET_DEC_H_INCLUDED
#define WAVELET_DEC_H_INCLUDED
#include <cstddef>
#include "wavelet_level.h"
namespace rtengine {
class wavelet_decomposition
{
typedef int internal_type;
static const int maxlevels = 8;
int nlevels;
size_t m_w, m_h;
size_t m_w1, m_h1;
wavelet_level<internal_type> * m_c[maxlevels];
public:
wavelet_decomposition(unsigned short ** src, size_t w, size_t h);
~wavelet_decomposition();
void reconstruct(unsigned short ** dst, const int * c);
};
//////////////////////////////////////////////////////////////////////////////
};
#endif

208
rtengine/wavelet_level.h Normal file
View File

@ -0,0 +1,208 @@
/*
* This file is part of RawTherapee.
*
* 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 <http://www.gnu.org/licenses/>.
*
* 2010 Ilya Popov <ilia_popov@rambler.ru>
*/
#ifndef WAVELET_LEVEL_H_INCLUDED
#define WAVELET_LEVEL_H_INCLUDED
#include <cstddef>
#include <algorithm>
#include "wavelet.h"
namespace rtengine
{
template<class T>
inline T clip(T x, T min_value, T max_value)
{
if(x < min_value)
return min_value;
if(x > max_value)
return max_value;
return x;
}
template <class A, class B>
void plane_copy(A ** a, B ** b, size_t w, size_t h)
{
for(size_t j = 0; j < h; j++)
for(size_t i = 0; i < w; i++)
b[j][i] = static_cast<B>(a[j][i]);
}
//////////////////////////////////////////////////////////////////////////////
template<class T>
class wavelet_level
{
// full size
size_t m_w, m_h;
// size of low frequency part
size_t m_w2, m_h2;
// distance between lines in the array of coeffs
size_t m_pitch;
// array of pointers to lines of coeffs
// actually is a single contiguous data array pointed by m_coeffs[0]
T ** m_coeffs;
// allocation and destruction of data storage
void create();
void destroy();
void dwt_2d(size_t w, size_t h);
void idwt_2d(size_t w, size_t h, int alpha);
public:
static const bool CLIP = true;
template<class E>
wavelet_level(E ** src, size_t w, size_t h)
: m_w(w), m_h(h), m_w2((w+1)/2), m_h2((h+1)/2), m_pitch(0), m_coeffs(NULL)
{
create();
decompose(src);
}
~wavelet_level()
{
destroy();
}
T ** lowfreq() const
{
return m_coeffs;
}
size_t lfw() const
{
return m_w2;
}
size_t lfh() const
{
return m_h2;
}
template<class E>
void decompose(E ** src);
template<class E>
void reconstruct(E ** dst, int alpha, bool do_clip = false);
};
//////////////////////////////////////////////////////////////////////////////
template<class T>
void wavelet_level<T>::dwt_2d(size_t w, size_t h)
{
T * buffer = new T[std::max(w, h) + 4];
for(size_t j = 0; j < h; j++)
{
//dwt_haar(m_coeffs[j], 1, buffer, w);
dwt_53(m_coeffs[j], 1, buffer, w);
}
for(size_t i = 0; i < w; i++)
{
//dwt_haar(&m_coeffs[0][i], m_pitch, buffer, h);
dwt_53(&m_coeffs[0][i], m_pitch, buffer, h);
}
delete buffer;
}
template<class T>
void wavelet_level<T>::idwt_2d(size_t w, size_t h, int alpha)
{
T * buffer = new T[std::max(w, h) + 4];
for(size_t j = 0; j < h; j++)
{
//idwt_haar(m_coeffs[j], 1, buffer, w, alpha);
idwt_53(m_coeffs[j], 1, buffer, w, alpha);
}
for(size_t i = 0; i < w; i++)
{
//idwt_haar(&m_coeffs[0][i], m_pitch, buffer, h, alpha);
idwt_53(&m_coeffs[0][i], m_pitch, buffer, h, alpha);
}
delete buffer;
}
template<class T>
void wavelet_level<T>::create()
{
// 16-byte alignment: no effect
//m_pitch = (((m_w*sizeof(T) + 15) / 16) * 16) / sizeof(T);
m_pitch = m_w;
T * data = new T[m_pitch * m_h];
m_coeffs = new T*[m_h];
for(size_t j = 0; j < m_h; j++)
{
m_coeffs[j] = data + m_pitch * j;
}
}
template<class T>
void wavelet_level<T>::destroy()
{
if(m_coeffs)
{
delete[] m_coeffs[0];
delete[] m_coeffs;
}
}
template<class T> template<class E>
void wavelet_level<T>::decompose(E ** src)
{
plane_copy(src, m_coeffs, m_w, m_h);
dwt_2d(m_w, m_h);
}
template<class T> template<class E>
void wavelet_level<T>::reconstruct(E ** dst, int alpha, bool do_clip)
{
idwt_2d(m_w, m_h, alpha);
if(do_clip)
{
for(size_t j = 0; j < m_h; j++)
for(size_t i = 0; i < m_w; i++)
m_coeffs[j][i] = clip(m_coeffs[j][i], 0, 65535);
}
plane_copy(m_coeffs, dst, m_w, m_h);
}
};
#endif

View File

@ -23,7 +23,8 @@ set (BASESOURCEFILES
thumbbrowserentrybase.cc batchqueueentry.cc thumbbrowserentrybase.cc batchqueueentry.cc
batchqueue.cc lwbutton.cc lwbuttonset.cc batchqueue.cc lwbutton.cc lwbuttonset.cc
batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc
profilestore.cc partialpastedlg.cc) profilestore.cc partialpastedlg.cc
equalizer.cc)
if (WIN32) if (WIN32)
set (EXTRA_SRC windirmonitor.cc myicon.o) set (EXTRA_SRC windirmonitor.cc myicon.o)

View File

@ -20,8 +20,8 @@
#define _COLORBOOST_H_ #define _COLORBOOST_H_
#include <gtkmm.h> #include <gtkmm.h>
#include <adjuster.h> #include "adjuster.h"
#include <toolpanel.h> #include "toolpanel.h"
class ColorBoost : public Gtk::VBox, public AdjusterListener, public ToolPanel { class ColorBoost : public Gtk::VBox, public AdjusterListener, public ToolPanel {

167
rtgui/equalizer.cc Normal file
View File

@ -0,0 +1,167 @@
/*
* This file is part of RawTherapee.
*
* 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 <http://www.gnu.org/licenses/>.
*
* 2010 Ilya Popov <ilia_popov@rambler.ru>
*/
#include <equalizer.h>
using namespace rtengine;
using namespace rtengine::procparams;
Equalizer::Equalizer () : ToolPanel() {
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (true);
pack_start(*enabled);
enabled->show();
enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &Equalizer::enabled_toggled) );
Gtk::HSeparator *separator = Gtk::manage (new Gtk::HSeparator());
pack_start(*separator, Gtk::PACK_SHRINK, 2);
for(int i = 0; i < 8; i++)
{
std::stringstream ss;
ss << i;
if(i == 0)
ss << " (" << M("TP_EQUALIZER_FINEST") << ")";
if(i == 7)
ss << " (" << M("TP_EQUALIZER_LARGEST") << ")";
correction[i] = new Adjuster (ss.str(), -100, 100, 1, 0);
correction[i]->setAdjusterListener(this);
pack_start(*correction[i]);
}
show_all_children ();
}
Equalizer::~Equalizer () {
}
void Equalizer::read (const ProcParams* pp, const ParamsEdited* pedited) {
disableListener ();
if (pedited) {
enabled->set_inconsistent (!pedited->equalizer.enabled);
for(int i = 0; i < 8; i++) {
correction[i]->setEditedState (pedited->equalizer.c[i] ? Edited : UnEdited);
}
}
enaConn.block (true);
enabled->set_active (pp->equalizer.enabled);
enaConn.block (false);
lastEnabled = pp->equalizer.enabled;
for (int i = 0; i < 8; i++) {
correction[i]->setValue(pp->equalizer.c[i]);
}
enableListener ();
}
void Equalizer::write (ProcParams* pp, ParamsEdited* pedited) {
pp->equalizer.enabled = enabled->get_active ();
for (int i = 0; i < 8; i++) {
pp->equalizer.c[i] = (int) correction[i]->getValue();
}
if (pedited) {
pedited->equalizer.enabled = !enabled->get_inconsistent();
for(int i = 0; i < 8; i++) {
pedited->equalizer.c[i] = correction[i]->getEditedState();
}
}
}
void Equalizer::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) {
for (int i = 0; i < 8; i++) {
correction[i]->setDefault(defParams->equalizer.c[i]);
}
if (pedited) {
for (int i = 0; i < 8; i++) {
correction[i]->setDefaultEditedState(pedited->equalizer.c[i] ? Edited : UnEdited);
}
}
else {
for (int i = 0; i < 8; i++) {
correction[i]->setDefaultEditedState(Irrelevant);
}
}
}
void Equalizer::setBatchMode (bool batchMode) {
ToolPanel::setBatchMode (batchMode);
for (int i = 0; i < 8; i++) {
correction[i]->showEditedCB();
}
}
void Equalizer::adjusterChanged (Adjuster* a, double newval) {
if (listener && enabled->get_active()) {
std::stringstream ss;
ss << "(";
int i;
for (i = 0; i < 8; i++) {
if (i > 0) {
ss << ", ";
}
ss << static_cast<int>(correction[i]->getValue());
}
ss << ")";
listener->panelChanged (EvEqualizer, ss.str());
}
}
void Equalizer::enabled_toggled () {
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 (EvEqlEnabled, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvEqlEnabled, M("GENERAL_DISABLED"));
}
}

53
rtgui/equalizer.h Normal file
View File

@ -0,0 +1,53 @@
/*
* This file is part of RawTherapee.
*
* 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 <http://www.gnu.org/licenses/>.
*
* 2010 Ilya Popov <ilia_popov@rambler.ru>
*/
#ifndef EQUALIZE_H_INCLUDED
#define EQUALIZE_H_INCLUDED
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class Equalizer : public Gtk::VBox, public AdjusterListener, public ToolPanel
{
protected:
Gtk::CheckButton * enabled;
Adjuster* correction[8];
sigc::connection enaConn;
bool lastEnabled;
public:
Equalizer ();
virtual ~Equalizer ();
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 enabled_toggled ();
};
#endif

View File

@ -119,6 +119,11 @@ void ParamsEdited::set (bool v) {
icm.gammaOnInput = v; icm.gammaOnInput = v;
icm.working = v; icm.working = v;
icm.output = v; icm.output = v;
equalizer.enabled = v;
for(int i = 0; i < 8; i++)
{
equalizer.c[i] = v;
}
exif.clear (); exif.clear ();
iptc.clear (); iptc.clear ();
} }
@ -226,6 +231,10 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
icm.gammaOnInput = icm.gammaOnInput && p.icm.gammaOnInput == other.icm.gammaOnInput; icm.gammaOnInput = icm.gammaOnInput && p.icm.gammaOnInput == other.icm.gammaOnInput;
icm.working = icm.working && p.icm.working == other.icm.working; icm.working = icm.working && p.icm.working == other.icm.working;
icm.output = icm.output && p.icm.output == other.icm.output; icm.output = icm.output && p.icm.output == other.icm.output;
equalizer.enabled = equalizer.enabled && p.equalizer.enabled == other.equalizer.enabled;
for(int i = 0; i < 8; i++) {
equalizer.c[i] = equalizer.c[i] && p.equalizer.c[i] == other.equalizer.c[i];
}
// exif = exif && p.exif==other.exif // exif = exif && p.exif==other.exif
// iptc = other.iptc; // iptc = other.iptc;
} }
@ -324,6 +333,10 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (icm.gammaOnInput) toEdit.icm.gammaOnInput = mods.icm.gammaOnInput; if (icm.gammaOnInput) toEdit.icm.gammaOnInput = mods.icm.gammaOnInput;
if (icm.working) toEdit.icm.working = mods.icm.working; if (icm.working) toEdit.icm.working = mods.icm.working;
if (icm.output) toEdit.icm.output = mods.icm.output; if (icm.output) toEdit.icm.output = mods.icm.output;
if (equalizer.enabled) toEdit.equalizer.enabled = mods.equalizer.enabled;
for(int i = 0; i < 8; i++) {
if(equalizer.c[i]) toEdit.equalizer.c[i] = mods.equalizer.c[i];
}
// if (exif) toEdit.exif==mo.exif = mods.exif==other.exif; // if (exif) toEdit.exif==mo.exif = mods.exif==other.exif;
// if (iptc;) toEdit.iptc==other.iptc; = mods.iptc==other.iptc;; // if (iptc;) toEdit.iptc==other.iptc; = mods.iptc==other.iptc;;
} }

View File

@ -215,6 +215,13 @@ class ColorManagementParamsEdited {
bool output; bool output;
}; };
class EqualizerParamsEdited {
public:
bool enabled;
bool c[8];
};
class ExifPairEdited { class ExifPairEdited {
public: public:
@ -253,6 +260,7 @@ class ParamsEdited {
HRecParamsEdited hlrecovery; HRecParamsEdited hlrecovery;
ResizeParamsEdited resize; ResizeParamsEdited resize;
ColorManagementParamsEdited icm; ColorManagementParamsEdited icm;
EqualizerParamsEdited equalizer;
std::vector<ExifPairEdited> exif; std::vector<ExifPairEdited> exif;
std::vector<IPTCPairEdited> iptc; std::vector<IPTCPairEdited> iptc;

View File

@ -53,6 +53,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
icm = Gtk::manage (new ICMPanel ()); icm = Gtk::manage (new ICMPanel ());
exifpanel = Gtk::manage (new ExifPanel ()); exifpanel = Gtk::manage (new ExifPanel ());
iptcpanel = Gtk::manage (new IPTCPanel ()); iptcpanel = Gtk::manage (new IPTCPanel ());
equalizer = Gtk::manage (new Equalizer ());
addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance); addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance);
addPanel (exposurePanel, curve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (curve); addPanel (exposurePanel, curve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (curve);
@ -65,6 +66,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (exposurePanel, lcurve, M("TP_LUMACURVE_LABEL")); toolPanels.push_back (lcurve); addPanel (exposurePanel, lcurve, M("TP_LUMACURVE_LABEL")); toolPanels.push_back (lcurve);
addPanel (detailsPanel, lumadenoise, M("TP_LUMADENOISE_LABEL")); toolPanels.push_back (lumadenoise); addPanel (detailsPanel, lumadenoise, M("TP_LUMADENOISE_LABEL")); toolPanels.push_back (lumadenoise);
addPanel (detailsPanel, colordenoise, M("TP_COLORDENOISE_LABEL")); toolPanels.push_back (colordenoise); addPanel (detailsPanel, colordenoise, M("TP_COLORDENOISE_LABEL")); toolPanels.push_back (colordenoise);
addPanel (detailsPanel, equalizer, M("TP_EQUALIZER_LABEL")); toolPanels.push_back (equalizer);
addPanel (transformPanel, crop, M("TP_CROP_LABEL")); toolPanels.push_back (crop); addPanel (transformPanel, crop, M("TP_CROP_LABEL")); toolPanels.push_back (crop);
addPanel (transformPanel, resize, M("TP_RESIZE_LABEL")); toolPanels.push_back (resize); addPanel (transformPanel, resize, M("TP_RESIZE_LABEL")); toolPanels.push_back (resize);
addPanel (transformPanel, lensgeom, M("TP_LENSGEOM_LABEL")); toolPanels.push_back (lensgeom); addPanel (transformPanel, lensgeom, M("TP_LENSGEOM_LABEL")); toolPanels.push_back (lensgeom);

View File

@ -51,6 +51,7 @@
#include <toolbar.h> #include <toolbar.h>
#include <lensgeom.h> #include <lensgeom.h>
#include <lensgeomlistener.h> #include <lensgeomlistener.h>
#include <equalizer.h>
class ImageEditorCoordinator; class ImageEditorCoordinator;
@ -86,6 +87,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
ColorDenoise* colordenoise; ColorDenoise* colordenoise;
Sharpening* sharpening; Sharpening* sharpening;
LCurve* lcurve; LCurve* lcurve;
Equalizer * equalizer;
std::vector<PParamsChangeListener*> paramcListeners; std::vector<PParamsChangeListener*> paramcListeners;