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

@ -363,14 +363,14 @@ PREFERENCES_DATEFORMAT;Date Format
PREFERENCES_DATEFORMATHINT;<i>You can use the following formatting strings:</i>\n<b>%y</b><i> : year</i>\n<b>%m</b><i> : month</i>\n<b>%d</b><i> : day</i>\n<i>\nFor example, the hungarian date format is:</i>\n<b>%y/%m/%d</b>
PREFERENCES_DCBENHANCE;Apply DCB enhancment step
PREFERENCES_DCBITERATIONS;Number of DCB iterations
#Emil's CA autocorrection
PREFERENCES_CACORRECTION;Apply CA auto correction
#Emil's CA autocorrection
PREFERENCES_CACORRECTION;Apply CA auto correction
#Emil's hot/dead pixel filter
PREFERENCES_HOTDEADPIXFILT;Apply hot/dead pixel filter
#Emil's line noise filter
PREFERENCES_LINEDENOISE;Line noise filter
PREFERENCES_GREENEQUIL;Green equilibration
PREFERENCES_HOTDEADPIXFILT;Apply hot/dead pixel filter
#Emil's line noise filter
PREFERENCES_LINEDENOISE;Line noise filter
PREFERENCES_GREENEQUIL;Green equilibration
PREFERENCES_DEFAULTLANG;Default language
PREFERENCES_DEFAULTTHEME;Default theme
PREFERENCES_DEMOSAICINGALGO;Demosaicing Algorithm
@ -525,6 +525,9 @@ TP_CROP_X;x
TP_CROP_Y;y
TP_DISTORTION_AMOUNT;Amount
TP_DISTORTION_LABEL;Distortion
TP_EQUALIZER_LABEL;Wavelet equalizer
TP_EQUALIZER_FINEST;finest
TP_EQUALIZER_LARGEST;coarsest
TP_EXPOSURE_AUTOLEVELS;Auto Levels
TP_EXPOSURE_BLACKLEVEL;Black
TP_EXPOSURE_BRIGHTNESS;Brightness
@ -643,62 +646,62 @@ TP_RESIZE_WIDTH;Width
TP_RESIZE_HEIGHT;Height
MAIN_TOGGLE_BEFORE_AFTER;B|A
###
###
EXIFFILTER_METADATAFILTER;Enable Metadata Filters
CURVEEDITOR_PARAMETRIC;Parametric
CURVEEDITOR_CUSTOM;Custom
CURVEEDITOR_TYPE;Type:
CURVEEDITOR_HIGHLIGHTS;Highlights
CURVEEDITOR_LIGHTS;Lights
CURVEEDITOR_DARKS;Darks
CURVEEDITOR_SHADOWS;Shadows
BATCH_PROCESSING;batch processing
PREFERENCES_BATCH_PROCESSING;batch processing
PREFERENCES_BEHAVIOR;Behavior
PREFERENCES_PROPERTY;Property
PREFERENCES_ADD;ADD
PREFERENCES_SET;SET
PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser
MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving
FILEBROWSER_CURRENT_NAME;Current name:
FILEBROWSER_NEW_NAME;New name:
FILEBROWSER_USETEMPLATE;Use template:
FILEBROWSER_ADDDELTEMPLATE;Add/Del templates...
ZOOMPANEL_ZOOMIN;Zoom In
ZOOMPANEL_ZOOMOUT;Zoom Out
ZOOMPANEL_ZOOM100;Zoom to 100%
ZOOMPANEL_ZOOMFITSCREEN;Fit to screen
ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window
ZOOMPANEL_100;(100%)
###
MAIN_BUTTON_FULLSCREEN;Fullscreen
MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen
PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails
NAVIGATOR_R_NA;R = n/a
NAVIGATOR_G_NA;G = n/a
NAVIGATOR_B_NA;B = n/a
NAVIGATOR_H_NA;H = n/a
NAVIGATOR_S_NA;S = n/a
NAVIGATOR_V_NA;V = n/a
NAVIGATOR_R_VALUE;R = %1
NAVIGATOR_G_VALUE;G = %1
NAVIGATOR_B_VALUE;B = %1
NAVIGATOR_H_VALUE;H = %1
NAVIGATOR_S_VALUE;S = %1
NAVIGATOR_V_VALUE;V = %1
NAVIGATOR_XY_NA;x = n/a, y = n/a
FILEBROWSER_SHOWEXIFINFO;Show EXIF info
TP_RESIZE_DOWNSCALEB;Downscale (Better)
TP_RESIZE_DOWNSCALEF;Downscale (Faster)
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
HISTOGRAM_BUTTON_R;R
HISTOGRAM_BUTTON_G;G
HISTOGRAM_BUTTON_B;B
HISTOGRAM_BUTTON_L;L
###
###
EXIFFILTER_METADATAFILTER;Enable Metadata Filters
CURVEEDITOR_PARAMETRIC;Parametric
CURVEEDITOR_CUSTOM;Custom
CURVEEDITOR_TYPE;Type:
CURVEEDITOR_HIGHLIGHTS;Highlights
CURVEEDITOR_LIGHTS;Lights
CURVEEDITOR_DARKS;Darks
CURVEEDITOR_SHADOWS;Shadows
BATCH_PROCESSING;batch processing
PREFERENCES_BATCH_PROCESSING;batch processing
PREFERENCES_BEHAVIOR;Behavior
PREFERENCES_PROPERTY;Property
PREFERENCES_ADD;ADD
PREFERENCES_SET;SET
PROGRESSDLG_PROFILECHANGEDINBROWSER;Profile changed in browser
MAIN_MSG_ERRORDURINGIMAGESAVING;Error during image saving
FILEBROWSER_CURRENT_NAME;Current name:
FILEBROWSER_NEW_NAME;New name:
FILEBROWSER_USETEMPLATE;Use template:
FILEBROWSER_ADDDELTEMPLATE;Add/Del templates...
ZOOMPANEL_ZOOMIN;Zoom In
ZOOMPANEL_ZOOMOUT;Zoom Out
ZOOMPANEL_ZOOM100;Zoom to 100%
ZOOMPANEL_ZOOMFITSCREEN;Fit to screen
ZOOMPANEL_NEWCROPWINDOW;Open (new) detail window
ZOOMPANEL_100;(100%)
###
MAIN_BUTTON_FULLSCREEN;Fullscreen
MAIN_BUTTON_UNFULLSCREEN;Exit fullscreen
PREFERENCES_OVERLAY_FILENAMES;Overlay filenames on thumbnails
NAVIGATOR_R_NA;R = n/a
NAVIGATOR_G_NA;G = n/a
NAVIGATOR_B_NA;B = n/a
NAVIGATOR_H_NA;H = n/a
NAVIGATOR_S_NA;S = n/a
NAVIGATOR_V_NA;V = n/a
NAVIGATOR_R_VALUE;R = %1
NAVIGATOR_G_VALUE;G = %1
NAVIGATOR_B_VALUE;B = %1
NAVIGATOR_H_VALUE;H = %1
NAVIGATOR_S_VALUE;S = %1
NAVIGATOR_V_VALUE;V = %1
NAVIGATOR_XY_NA;x = n/a, y = n/a
FILEBROWSER_SHOWEXIFINFO;Show EXIF info
TP_RESIZE_DOWNSCALEB;Downscale (Better)
TP_RESIZE_DOWNSCALEF;Downscale (Faster)
SAVEDLG_TIFFUNCOMPRESSED;Uncompressed TIFF
HISTOGRAM_BUTTON_R;R
HISTOGRAM_BUTTON_G;G
HISTOGRAM_BUTTON_B;B
HISTOGRAM_BUTTON_L;L

File diff suppressed because it is too large Load Diff

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
stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.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})
#It may be nice to store library version too

View File

@ -89,6 +89,7 @@ class ImProcFunctions {
void lab2rgb (LabImage* lab, Image8* image);
void resize (Image16* src, Image16* dst);
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);
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>
#define NUMOFEVENTS 84
#define NUMOFEVENTS 86
namespace rtengine {
@ -109,7 +109,9 @@ enum ProcEvent {
EvResizeEnabled=80,
EvProfileChangeNotification=81,
EvSHHighQuality=82,
EvPerspCorr=83
EvPerspCorr=83,
EvEqualizer=84,
EvEqlEnabled=85
};
}
#endif

View File

@ -158,6 +158,12 @@ void ProcParams::setDefaults () {
icm.working = "sRGB";
icm.output = "sRGB";
equalizer.enabled = false;
for(int i = 0; i < 8; i ++)
{
equalizer.c[i] = 0;
}
exif.clear ();
iptc.clear ();
@ -303,6 +309,15 @@ int ProcParams::save (Glib::ustring fname) const {
keyFile.set_boolean ("Color Management", "ApplyGammaBeforeInputProfile", icm.gammaOnInput);
keyFile.set_string ("Color Management", "WorkingProfile", icm.working);
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
for (int i=0; i<exif.size(); i++)
@ -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");
}
// 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
if (keyFile.has_group ("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) {
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.working == other.icm.working
&& icm.output == other.icm.output
&& equalizer == other.equalizer
&& exif==other.exif
&& iptc==other.iptc;
}

View File

@ -204,16 +204,16 @@ class DistortionParams {
bool uselensfun;
double amount;
};
/**
* Parameters of the perspective correction
*/
class PerspectiveParams {
public:
int horizontal;
int vertical;
};
/**
* Parameters of the perspective correction
*/
class PerspectiveParams {
public:
int horizontal;
int vertical;
};
/**
* Parameters of the vignetting correction
@ -302,6 +302,16 @@ class IPTCPair {
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
*/
@ -321,14 +331,15 @@ class ProcParams {
CoarseTransformParams coarse; ///< Coarse transformation (90, 180, 270 deg rotation, h/v flipping) parameters
CommonTransformParams commonTrans; ///< Common transformation parameters (autofill)
RotateParams rotate; ///< Rotation parameters
DistortionParams distortion; ///< Lens distortion correction parameters
PerspectiveParams perspective; ///< Perspective correction parameters
DistortionParams distortion; ///< Lens distortion correction parameters
PerspectiveParams perspective; ///< Perspective correction parameters
CACorrParams cacorrection; ///< Lens c/a correction parameters
VignettingParams vignetting; ///< Lens vignetting correction parameters
ChannelMixerParams chmixer; ///< Channel mixer parameters
HRecParams hlrecovery; ///< Highlight recovery parameters
ResizeParams resize; ///< Resize parameters
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<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

View File

@ -19,89 +19,90 @@
#include <refreshmap.h>
int refreshmap[] = {
ALL, // EvPhotoLoaded,
ALL, // EvProfileLoaded,
ALL, // EvProfileChanged,
ALL, // EvHistoryBrowsed,
RGBCURVE, // EvBrightness,
RGBCURVE, // EvContrast,
RGBCURVE, // EvBlack,
RGBCURVE, // EvExpComp,
RGBCURVE, // EvHLCompr,
RGBCURVE, // EvSHCompr,
RGBCURVE, // EvToneCurve,
AUTOEXP, // EvAutoExp,
AUTOEXP, // EvClip,
LUMINANCECURVE, // EvLBrightness,
LUMINANCECURVE, // EvLContrast,
LUMINANCECURVE, // EvLBlack,
LUMINANCECURVE, // EvLHLCompr,
LUMINANCECURVE, // EvLSHCompr,
LUMINANCECURVE, // EvLCurve,
SHARPENING, // EvShrEnabled,
SHARPENING, // EvShrRadius,
SHARPENING, // EvShrAmount,
SHARPENING, // EvShrThresh,
SHARPENING, // EvShrEdgeOnly,
SHARPENING, // EvShrEdgeRadius,
SHARPENING, // EvShrEdgeTolerance,
SHARPENING, // EvShrHaloControl,
SHARPENING, // EvShrHaloAmount,
SHARPENING, // EvShrMethod,
SHARPENING, // EvShrDRadius,
SHARPENING, // EvShrDAmount,
SHARPENING, // EvShrDDamping,
SHARPENING, // EvShrDIterations,
COLORBOOST, // EvCBAvoidClip,
COLORBOOST, // EvCBSatLimiter,
COLORBOOST, // EvCBSatLimit,
COLORBOOST, // EvCBBoost,
WHITEBALANCE, // EvWBMethod,
WHITEBALANCE, // EvWBTemp,
WHITEBALANCE, // EvWBGreen,
COLORBOOST, // EvCShiftA,
COLORBOOST, // EvCShiftB,
LUMADENOISE, // EvLDNEnabled,
LUMADENOISE, // EvLDNRadius,
LUMADENOISE, // EvLDNEdgeTolerance,
COLORDENOISE, // EvCDNEnabled,
COLORDENOISE, // EvCDNRadius,
COLORDENOISE, // EvCDNEdgeTolerance,
COLORDENOISE, // EvCDNEdgeSensitive,
RETINEX, // EvSHEnabled,
RGBCURVE, // EvSHHighlights,
RGBCURVE, // EvSHShadows,
RGBCURVE, // EvSHHLTonalW,
RGBCURVE, // EvSHSHTonalW,
RGBCURVE, // EvSHLContrast,
RETINEX, // EvSHRadius,
ALL, // EvCTRotate,
ALL, // EvCTHFlip,
ALL, // EvCTVFlip,
TRANSFORM, // EvROTDegree,
TRANSFORM, // EvTransAutoFill,
TRANSFORM, // EvDISTAmount,
ALL, // EvBookmarkSelected,
CROP, // EvCrop,
TRANSFORM, // EvCACorr,
ALL, // EvHREnabled,
ALL, // EvHRAmount,
ALL, // EvHRMethod,
ALL, // EvWProfile,
ALL, // EvOProfile,
ALL, // EvIProfile,
TRANSFORM, // EvVignetting,
RGBCURVE, // EvChMixer,
ALL, // EvResizeScale,
ALL, // EvResizeMethod,
EXIF, // EvExif,
IPTC, // EvIPTC
ALL, // EvResizeSpec,
ALL, // EvResizeWidth
ALL, // EvResizeHeight
ALL, // EvResizeEnabled
ALL, // EvProfileChangeNotification
ALL, // EvPhotoLoaded,
ALL, // EvProfileLoaded,
ALL, // EvProfileChanged,
ALL, // EvHistoryBrowsed,
RGBCURVE, // EvBrightness,
RGBCURVE, // EvContrast,
RGBCURVE, // EvBlack,
RGBCURVE, // EvExpComp,
RGBCURVE, // EvHLCompr,
RGBCURVE, // EvSHCompr,
RGBCURVE, // EvToneCurve,
AUTOEXP, // EvAutoExp,
AUTOEXP, // EvClip,
LUMINANCECURVE, // EvLBrightness,
LUMINANCECURVE, // EvLContrast,
LUMINANCECURVE, // EvLBlack,
LUMINANCECURVE, // EvLHLCompr,
LUMINANCECURVE, // EvLSHCompr,
LUMINANCECURVE, // EvLCurve,
SHARPENING, // EvShrEnabled,
SHARPENING, // EvShrRadius,
SHARPENING, // EvShrAmount,
SHARPENING, // EvShrThresh,
SHARPENING, // EvShrEdgeOnly,
SHARPENING, // EvShrEdgeRadius,
SHARPENING, // EvShrEdgeTolerance,
SHARPENING, // EvShrHaloControl,
SHARPENING, // EvShrHaloAmount,
SHARPENING, // EvShrMethod,
SHARPENING, // EvShrDRadius,
SHARPENING, // EvShrDAmount,
SHARPENING, // EvShrDDamping,
SHARPENING, // EvShrDIterations,
COLORBOOST, // EvCBAvoidClip,
COLORBOOST, // EvCBSatLimiter,
COLORBOOST, // EvCBSatLimit,
COLORBOOST, // EvCBBoost,
WHITEBALANCE, // EvWBMethod,
WHITEBALANCE, // EvWBTemp,
WHITEBALANCE, // EvWBGreen,
COLORBOOST, // EvCShiftA,
COLORBOOST, // EvCShiftB,
LUMADENOISE, // EvLDNEnabled,
LUMADENOISE, // EvLDNRadius,
LUMADENOISE, // EvLDNEdgeTolerance,
COLORDENOISE, // EvCDNEnabled,
COLORDENOISE, // EvCDNRadius,
COLORDENOISE, // EvCDNEdgeTolerance,
COLORDENOISE, // EvCDNEdgeSensitive,
RETINEX, // EvSHEnabled,
RGBCURVE, // EvSHHighlights,
RGBCURVE, // EvSHShadows,
RGBCURVE, // EvSHHLTonalW,
RGBCURVE, // EvSHSHTonalW,
RGBCURVE, // EvSHLContrast,
RETINEX, // EvSHRadius,
ALL, // EvCTRotate,
ALL, // EvCTHFlip,
ALL, // EvCTVFlip,
TRANSFORM, // EvROTDegree,
TRANSFORM, // EvTransAutoFill,
TRANSFORM, // EvDISTAmount,
ALL, // EvBookmarkSelected,
CROP, // EvCrop,
TRANSFORM, // EvCACorr,
ALL, // EvHREnabled,
ALL, // EvHRAmount,
ALL, // EvHRMethod,
ALL, // EvWProfile,
ALL, // EvOProfile,
ALL, // EvIProfile,
TRANSFORM, // EvVignetting,
RGBCURVE, // EvChMixer,
ALL, // EvResizeScale,
ALL, // EvResizeMethod,
EXIF, // EvExif,
IPTC, // EvIPTC
ALL, // EvResizeSpec,
ALL, // EvResizeWidth
ALL, // EvResizeHeight
ALL, // EvResizeEnabled
ALL, // EvProfileChangeNotification
RETINEX, // EvShrHighQuality
TRANSFORM // EvPerspCorr
};
TRANSFORM, // EvPerspCorr
ALL // ????? EvEqualizer
};

View File

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

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
batchqueue.cc lwbutton.cc lwbuttonset.cc
batchqueuebuttonset.cc browserfilter.cc exiffiltersettings.cc
profilestore.cc partialpastedlg.cc)
profilestore.cc partialpastedlg.cc
equalizer.cc)
if (WIN32)
set (EXTRA_SRC windirmonitor.cc myicon.o)

View File

@ -20,8 +20,8 @@
#define _COLORBOOST_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
#include "adjuster.h"
#include "toolpanel.h"
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.working = v;
icm.output = v;
equalizer.enabled = v;
for(int i = 0; i < 8; i++)
{
equalizer.c[i] = v;
}
exif.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.working = icm.working && p.icm.working == other.icm.working;
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
// 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.working) toEdit.icm.working = mods.icm.working;
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 (iptc;) toEdit.iptc==other.iptc; = mods.iptc==other.iptc;;
}

View File

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

View File

@ -53,6 +53,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
icm = Gtk::manage (new ICMPanel ());
exifpanel = Gtk::manage (new ExifPanel ());
iptcpanel = Gtk::manage (new IPTCPanel ());
equalizer = Gtk::manage (new Equalizer ());
addPanel (colorPanel, whitebalance, M("TP_WBALANCE_LABEL")); toolPanels.push_back (whitebalance);
addPanel (exposurePanel, curve, M("TP_EXPOSURE_LABEL")); toolPanels.push_back (curve);
@ -65,10 +66,11 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (exposurePanel, lcurve, M("TP_LUMACURVE_LABEL")); toolPanels.push_back (lcurve);
addPanel (detailsPanel, lumadenoise, M("TP_LUMADENOISE_LABEL")); toolPanels.push_back (lumadenoise);
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, resize, M("TP_RESIZE_LABEL")); toolPanels.push_back (resize);
addPanel (transformPanel, lensgeom, M("TP_LENSGEOM_LABEL")); toolPanels.push_back (lensgeom);
addPanel (lensgeom->getPackBox(), rotate, M("TP_ROTATE_LABEL")); toolPanels.push_back (rotate);
addPanel (lensgeom->getPackBox(), rotate, M("TP_ROTATE_LABEL")); toolPanels.push_back (rotate);
addPanel (lensgeom->getPackBox(), perspective, M("TP_PERSPECTIVE_LABEL")); toolPanels.push_back (perspective);
addPanel (lensgeom->getPackBox(), distortion, M("TP_DISTORTION_LABEL")); toolPanels.push_back (distortion);
addPanel (lensgeom->getPackBox(), cacorrection, M("TP_CACORRECTION_LABEL")); toolPanels.push_back (cacorrection);

View File

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