diff --git a/AUTHORS.txt b/AUTHORS.txt
index a1733a88e..1f7890d8b 100644
--- a/AUTHORS.txt
+++ b/AUTHORS.txt
@@ -8,6 +8,7 @@ Developement contributors, in last name alphabetical order:
Martin Burri
Javier Celaya
Jacques Desmis
+ Pavlov Dmitry
Oliver Duis
Maciek Dworak
Michael Ezra
@@ -36,6 +37,7 @@ Other contributors (profiles, ideas, mockups, testing, forum activity, translati
Thorsten Bartolomäus
Patrik Brunner
Fernando Carello
+ Pat David
Reine Edvardsson
André Gauthier
Sébastien Guyader
diff --git a/rtdata/languages/Deutsch b/rtdata/languages/Deutsch
index ae589f096..04d53f76b 100644
--- a/rtdata/languages/Deutsch
+++ b/rtdata/languages/Deutsch
@@ -623,7 +623,8 @@ PARTIALPASTE_METAICMGROUP;Gruppe Metadaten / ICM
PARTIALPASTE_PCVIGNETTE;Vignettierungsfilter
PARTIALPASTE_PERSPECTIVE;Perspektive
PARTIALPASTE_PREPROCESS_GREENEQUIL;Vorverarbeitung: Grün-Ausgleich
-PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Vorverarbeitung: Hot/Dead-Pixel-Filter anwenden
+PARTIALPASTE_PREPROCESS_HOTPIXFILT;Vorverarbeitung: Hot-Pixel-Filter
+PARTIALPASTE_PREPROCESS_DEADPIXFILT;Vorverarbeitung: Dead-Pixel-Filter
PARTIALPASTE_PREPROCESS_LINEDENOISE;Vorverarbeitung: Zeilenrauschfilter
PARTIALPASTE_RAWCACORR_AUTO;Chromatische Aberration: Automatische Korrektur
PARTIALPASTE_RAWCACORR_CABLUE;Chromatische Aberration: Blau
@@ -633,7 +634,7 @@ PARTIALPASTE_RAWEXPOS_LINEAR;RAW-Weiß/Schwarz-Punkt: Linearer Korrekturfaktor
PARTIALPASTE_RAWEXPOS_PRESER;RAW-Weiß/Schwarz-Punkt: Lichter bewahren (EV)
PARTIALPASTE_RAWGROUP;Gruppe RAW
PARTIALPASTE_RAW_ALLENHANCE;Farbinterpolation: Artifakt-/Rauschminderung
-PARTIALPASTE_RAW_DCBENHANCE;Farbinterpolation: DCB-Verfeinerungsschritt durchführen
+PARTIALPASTE_RAW_DCBENHANCE;Farbinterpolation: DCB-Verfeinerungsschritt
PARTIALPASTE_RAW_DCBITERATIONS;Farbinterpolation: Anzahl der DCB-Iterationen
PARTIALPASTE_RAW_DMETHOD;Farbinterpolation: Methode
PARTIALPASTE_RAW_FALSECOLOR;Farbinterpolation: Falschfarbenunterdrückung Stufen
@@ -1206,7 +1207,8 @@ TP_PERSPECTIVE_HORIZONTAL;Horizontal
TP_PERSPECTIVE_LABEL;Perspektive
TP_PERSPECTIVE_VERTICAL;Vertikal
TP_PREPROCESS_GREENEQUIL;Grün-Ausgleich
-TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead-Pixel-Filter anwenden
+TP_PREPROCESS_HOTPIXFILT;Hot-Pixel-Filter
+TP_PREPROCESS_DEADPIXFILT;Dead-Pixel-Filter
TP_PREPROCESS_HOTDEADPIXTHRESH;Hot/Dead-Pixel-Erkennung\nSchwellenwert
TP_PREPROCESS_LABEL;Vorverarbeitung
TP_PREPROCESS_LINEDENOISE;Zeilenrauschfilter
@@ -1223,7 +1225,7 @@ TP_RAWEXPOS_LINEAR;Weißpunkt: Linearer\nKorrekturfaktor
TP_RAWEXPOS_PRESER;Weißpunkt: Lichter\nbewahrende Korrektur (EV)
TP_RAWEXPOS_TWOGREEN;Grün-Werte automatisch angleichen
TP_RAW_ALLENHANCE;Artifakt-/Rauschminderung nach\nFarbinterpolation durchführen
-TP_RAW_DCBENHANCE;DCB-Verfeinerungsschritt durchführen
+TP_RAW_DCBENHANCE;DCB-Verfeinerungsschritt
TP_RAW_DCBITERATIONS;Anzahl der DCB-Iterationen
TP_RAW_DMETHOD;Methode
TP_RAW_FALSECOLOR;Falschfarbenunterdrückung\nStufen
diff --git a/rtdata/languages/Francais b/rtdata/languages/Francais
index ab7ff98e5..742358059 100644
--- a/rtdata/languages/Francais
+++ b/rtdata/languages/Francais
@@ -690,7 +690,8 @@ PARTIALPASTE_METAICMGROUP;Réglages des Métadonnées/ICM
PARTIALPASTE_PCVIGNETTE;Filtre Vignettage
PARTIALPASTE_PERSPECTIVE;Perspective
PARTIALPASTE_PREPROCESS_GREENEQUIL;Équilibrage du vert
-PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Filtrage des pixels chauds/morts
+PARTIALPASTE_PREPROCESS_HOTPIXFILT;Filtrage des pixels chauds
+PARTIALPASTE_PREPROCESS_DEADPIXFILT;Filtrage des pixels morts
PARTIALPASTE_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne
PARTIALPASTE_RAWCACORR_AUTO;Corr. auto. de l'aberr. chromatique
PARTIALPASTE_RAWCACORR_CABLUE;Aberr. chromatique bleu
@@ -1360,8 +1361,10 @@ TP_PERSPECTIVE_VERTICAL;Verticale
TP_PFCURVE_CURVEEDITOR_CH;Teinte
TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Contrôle la force du défrangeage en fonction de la couleur. En haut = action maxi, en bas = pas d'action sur la couleur.
TP_PREPROCESS_GREENEQUIL;Équilibrage du vert
-TP_PREPROCESS_HOTDEADPIXFILT;Filtrer les pixels chauds/morts
-TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Essaie de supprimer les pixels chauds/morts
+TP_PREPROCESS_HOTPIXFILT;Filtrer les pixels chauds
+TP_PREPROCESS_DEADPIXFILT;Filtrer les pixels morts
+TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Essaie de supprimer les pixels chauds
+TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Essaie de supprimer les pixels morts
TP_PREPROCESS_LABEL;Traitement pre-dématriçage
TP_PREPROCESS_LINEDENOISE;Filtre de bruit de ligne
TP_PREPROCESS_NO_FOUND;Aucun trouvé
diff --git a/rtdata/languages/default b/rtdata/languages/default
index 86fb524a6..993868fa6 100644
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -319,7 +319,7 @@ HISTORY_MSG_95;Lab - Chromaticity
HISTORY_MSG_96;'a' Curve
HISTORY_MSG_97;'b' Curve
HISTORY_MSG_98;Demosaicing Method
-HISTORY_MSG_99;Hot/Dead pixel filter
+HISTORY_MSG_99;Hot pixel filter
HISTORY_MSG_100;Saturation
HISTORY_MSG_101;HSV - Hue
HISTORY_MSG_102;HSV - Saturation
@@ -517,6 +517,7 @@ HISTORY_MSG_294;Film Simulation - Strength
HISTORY_MSG_295;Film Simulation - Film
HISTORY_MSG_296;NR - Modulate luminance
HISTORY_MSG_297;NR - Quality
+HISTORY_MSG_298;Dead pixel filter
HISTORY_NEWSNAPSHOT;Add
HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s
HISTORY_SNAPSHOTS;Snapshots
@@ -686,7 +687,8 @@ PARTIALPASTE_METAICMGROUP;Metadata/Color Management Settings
PARTIALPASTE_PCVIGNETTE;Vignette filter
PARTIALPASTE_PERSPECTIVE;Perspective
PARTIALPASTE_PREPROCESS_GREENEQUIL;Green equilibration
-PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT;Apply hot/dead pixel filter
+PARTIALPASTE_PREPROCESS_HOTPIXFILT;Apply hot pixel filter
+PARTIALPASTE_PREPROCESS_DEADPIXFILT;Apply dead pixel filter
PARTIALPASTE_PREPROCESS_LINEDENOISE;Line noise filter
PARTIALPASTE_RAWCACORR_AUTO;CA auto-correction
PARTIALPASTE_RAWCACORR_CABLUE;CA blue
@@ -1376,8 +1378,10 @@ TP_PERSPECTIVE_VERTICAL;Vertical
TP_PFCURVE_CURVEEDITOR_CH;Hue
TP_PFCURVE_CURVEEDITOR_CH_TOOLTIP;Controls defringe strength by color.\nHigher = more,\nLower = less.
TP_PREPROCESS_GREENEQUIL;Green Equilibration
-TP_PREPROCESS_HOTDEADPIXFILT;Hot/Dead pixel filter
-TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP;Tries to suppress hot and dead pixels.
+TP_PREPROCESS_HOTPIXFILT;Hot pixel filter
+TP_PREPROCESS_HOTPIXFILT_TOOLTIP;Tries to suppress hot pixels.
+TP_PREPROCESS_DEADPIXFILT;Dead pixel filter
+TP_PREPROCESS_DEADPIXFILT_TOOLTIP;Tries to suppress dead pixels.
TP_PREPROCESS_LABEL;Preprocessing
TP_PREPROCESS_LINEDENOISE;Line Noise Filter
TP_PREPROCESS_NO_FOUND;None found
diff --git a/rtengine/dfmanager.cc b/rtengine/dfmanager.cc
index 4d95fa93e..bb3a73728 100644
--- a/rtengine/dfmanager.cc
+++ b/rtengine/dfmanager.cc
@@ -26,7 +26,7 @@
#include
#include
#include "imagedata.h"
-
+
namespace rtengine{
extern const Settings* settings;
@@ -95,7 +95,7 @@ RawImage* dfInfo::getRawImage()
return ri;
}
-std::list& dfInfo::getHotPixels()
+std::vector& dfInfo::getHotPixels()
{
if( !ri ){
updateRawImage();
@@ -108,7 +108,7 @@ std::list& dfInfo::getHotPixels()
* the first file is used also for reading all information other than pixels
*/
void dfInfo::updateRawImage()
-{
+{
typedef unsigned int acc_t;
if( !pathNames.empty() ){
std::list::iterator iName = pathNames.begin();
@@ -171,27 +171,37 @@ void dfInfo::updateRawImage()
}
void dfInfo::updateBadPixelList( RawImage *df )
-{
- const int threshold=10;
- if( ri->getSensorType()!=ST_NONE ){
+{
+ const float threshold=10.f/8.f;
+ if( ri->getSensorType()!=ST_NONE ){
+ std::vector badPixelsTemp;
+
+#pragma omp parallel
+{
+ std::vector badPixelsThread;
+#pragma omp for nowait
for( int row=2; rowget_height()-2; row++)
for( int col=2; col < df->get_width()-2; col++){
- int m = (df->data[row-2][col-2] + df->data[row-2][col] + df->data[row-2][col+2]+
+ float m = (df->data[row-2][col-2] + df->data[row-2][col] + df->data[row-2][col+2]+
df->data[row][col-2] + df->data[row][col+2]+
- df->data[row+2][col-2] + df->data[row+2][col] + df->data[row+2][col+2])/8;
- if( df->data[row][col]/threshold > m )
- badPixels.push_back( badPix(col,row) );
- }
+ df->data[row+2][col-2] + df->data[row+2][col] + df->data[row+2][col+2]);
+ if( df->data[row][col] > m*threshold )
+ badPixelsThread.push_back( badPix(col,row) );
+ }
+#pragma omp critical
+ badPixelsTemp.insert(badPixelsTemp.end(),badPixelsThread.begin(),badPixelsThread.end());
+}
+ badPixels.insert(badPixels.end(),badPixelsTemp.begin(),badPixelsTemp.end());
}else{
for( int row=1; rowget_height()-1; row++)
for( int col=1; col < df->get_width()-1; col++){
- int m[3];
+ float m[3];
for( int c=0; c<3;c++){
m[c] = (df->data[row-1][3*(col-1)+c] + df->data[row-1][3*col+c] + df->data[row-1][3*(col+1)+c]+
df->data[row] [3*(col-1)+c] + df->data[row] [3*col+c]+
- df->data[row+1][3*(col-1)+c] + df->data[row+1][3*col+c] + df->data[row+1][3*(col+1)+c])/8;
+ df->data[row+1][3*(col-1)+c] + df->data[row+1][3*col+c] + df->data[row+1][3*(col+1)+c]);
}
- if( df->data[row][3*col]/threshold > m[0] || df->data[row][3*col+1]/threshold > m[1] || df->data[row][3*col+2]/threshold > m[2])
+ if( df->data[row][3*col] > m[0]*threshold || df->data[row][3*col+1] > m[1]*threshold || df->data[row][3*col+2] > m[2]*threshold)
badPixels.push_back( badPix(col,row) );
}
}
@@ -367,7 +377,7 @@ RawImage* DFManager::searchDarkFrame( const Glib::ustring filename )
return df->getRawImage();
return 0;
}
-std::list *DFManager::getHotPixels ( const Glib::ustring filename )
+std::vector *DFManager::getHotPixels ( const Glib::ustring filename )
{
for ( dfList_t::iterator iter = dfList.begin(); iter != dfList.end();iter++ ){
if( iter->second.pathname.compare( filename )==0 )
@@ -375,7 +385,7 @@ std::list *DFManager::getHotPixels ( const Glib::ustring filename )
}
return 0;
}
-std::list *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t )
+std::vector *DFManager::getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t )
{
dfInfo *df = find( mak, mod, iso, shut, t );
if( df ){
@@ -408,35 +418,64 @@ int DFManager::scanBadPixelsFile( Glib::ustring filename )
dirpos1= dirpos2;
std::string makmodel(filename,dirpos1+1,lastdot-(dirpos1+1) );
- std::list bp;
- char line[256];
- while( fgets(line,sizeof(line),file ) ){
- int x,y;
- if( sscanf(line,"%d %d",&x,&y) == 2 )
- bp.push_back( badPix(x,y) );
- }
+ std::vector bp;
+ char line[256];
+ if(fgets(line,sizeof(line),file )) {
+ int x,y;
+ int offset = 0;
+ int numparms = sscanf(line,"%d %d",&x,&y);
+ if( numparms == 1 ) // only one number in first line means, that this is the offset.
+ offset = x;
+ else if(numparms == 2)
+ bp.push_back( badPix(x+offset,y+offset) );
+ while( fgets(line,sizeof(line),file ) ){
+ if( sscanf(line,"%d %d",&x,&y) == 2 )
+ bp.push_back( badPix(x+offset,y+offset) );
+ }
+ }
int numPixels = bp.size();
- if( numPixels >0 )
+ if( numPixels >0 )
bpList[ makmodel ] = bp;
fclose(file);
return numPixels;
}
-std::list *DFManager::getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial)
+std::vector *DFManager::getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial)
{
- std::ostringstream s;
- s << mak << " " <verbose )
- printf("Found:%s.badpixels in list\n",s.str().c_str());
- return &(iter->second);
- }
- if( settings->verbose )
- printf("%s.badpixels not found\n",s.str().c_str());
- return 0;
+ bpList_t::iterator iter;
+ bool found = false;
+ if( !serial.empty() ) {
+ // search with sreial number first
+ std::ostringstream s;
+ s << mak << " " << mod << " " << serial;
+ iter = bpList.find( s.str() );
+ if( iter != bpList.end() )
+ found = true;
+ if( settings->verbose )
+ if(found)
+ printf("%s.badpixels found\n",s.str().c_str());
+ else
+ printf("%s.badpixels not found\n",s.str().c_str());
+
+ }
+ if(!found) {
+ // search without serial number
+ std::ostringstream s;
+ s << mak << " " <verbose )
+ if(found)
+ printf("%s.badpixels found\n",s.str().c_str());
+ else
+ printf("%s.badpixels not found\n",s.str().c_str());
+ }
+ if(!found) {
+ return 0;
+ } else {
+ return &(iter->second);
+ }
}
// Global variable
diff --git a/rtengine/dfmanager.h b/rtengine/dfmanager.h
index 3a171b714..11d110cc3 100644
--- a/rtengine/dfmanager.h
+++ b/rtengine/dfmanager.h
@@ -55,11 +55,11 @@ public:
std::string key(){ return key( maker,model,iso,shutter); }
RawImage *getRawImage();
- std::list &getHotPixels();
+ std::vector &getHotPixels();
protected:
RawImage *ri; ///< Dark Frame raw data
- std::list badPixels; ///< Extracted hot pixels
+ std::vector badPixels; ///< Extracted hot pixels
void updateBadPixelList( RawImage *df );
void updateRawImage();
@@ -73,13 +73,13 @@ public:
void getStat( int &totFiles, int &totTemplate);
RawImage *searchDarkFrame( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
RawImage *searchDarkFrame( const Glib::ustring filename );
- std::list *getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
- std::list *getHotPixels ( const Glib::ustring filename );
- std::list *getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial);
+ std::vector *getHotPixels ( const std::string &mak, const std::string &mod, int iso, double shut, time_t t );
+ std::vector *getHotPixels ( const Glib::ustring filename );
+ std::vector *getBadPixels ( const std::string &mak, const std::string &mod, const std::string &serial);
protected:
typedef std::multimap dfList_t;
- typedef std::map > bpList_t;
+ typedef std::map > bpList_t;
dfList_t dfList;
bpList_t bpList;
bool initialized;
diff --git a/rtengine/improccoordinator.cc b/rtengine/improccoordinator.cc
index 79566388b..5069c6ae8 100644
--- a/rtengine/improccoordinator.cc
+++ b/rtengine/improccoordinator.cc
@@ -155,7 +155,7 @@ void ImProcCoordinator::updatePreviewImage (int todo, Crop* cropCall) {
rp.bayersensor.ccSteps = 0;
rp.xtranssensor.ccSteps = 0;
- rp.hotdeadpix_filt = false;
+ rp.deadPixelFilter = rp.hotPixelFilter = false;
}
progress ("Applying white balance, color correction & sRGB conversion...",100*readyphase/numofphases);
diff --git a/rtengine/procevents.h b/rtengine/procevents.h
index f64776e00..1075d2ce6 100644
--- a/rtengine/procevents.h
+++ b/rtengine/procevents.h
@@ -120,7 +120,7 @@ enum ProcEvent {
EvLaCurve=95,
EvLbCurve=96,
EvDemosaicMethod=97,
- EvPreProcessHotDeadPixel=98,
+ EvPreProcessHotPixel=98,
EvSaturation=99,
EvHSVEqualizerH=100,
EvHSVEqualizerS=101,
@@ -322,6 +322,7 @@ enum ProcEvent {
EvFilmSimulationFilename=294,
EvDPDNLCurve=295,
EvDPDNsmet=296,
+ EvPreProcessDeadPixel=297,
NUMOFEVENTS
};
diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc
index f2856e58d..868d4b94d 100644
--- a/rtengine/procparams.cc
+++ b/rtengine/procparams.cc
@@ -835,7 +835,8 @@ void ProcParams::setDefaults () {
raw.cared = 0;
raw.cablue = 0;
raw.ca_autocorrect = false;
- raw.hotdeadpix_filt = false;
+ raw.hotPixelFilter = false;
+ raw.deadPixelFilter = false;
raw.hotdeadpix_thresh = 40;
exif.clear ();
iptc.clear ();
@@ -1494,7 +1495,8 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol
if (!pedited || pedited->raw.caCorrection) keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect );
if (!pedited || pedited->raw.caRed) keyFile.set_double ("RAW", "CARed", raw.cared );
if (!pedited || pedited->raw.caBlue) keyFile.set_double ("RAW", "CABlue", raw.cablue );
- if (!pedited || pedited->raw.hotDeadPixelFilter) keyFile.set_boolean ("RAW", "HotDeadPixels", raw.hotdeadpix_filt );
+ if (!pedited || pedited->raw.hotPixelFilter) keyFile.set_boolean ("RAW", "HotPixelFilter", raw.hotPixelFilter );
+ if (!pedited || pedited->raw.deadPixelFilter) keyFile.set_boolean ("RAW", "DeadPixelFilter", raw.deadPixelFilter );
if (!pedited || pedited->raw.hotDeadPixelThresh) keyFile.set_integer ("RAW", "HotDeadPixelThresh", raw.hotdeadpix_thresh );
if (!pedited || pedited->raw.bayersensor.method) keyFile.set_string ("RAW Bayer", "Method", raw.bayersensor.method );
@@ -2201,7 +2203,11 @@ if (keyFile.has_group ("RAW")) {
if (keyFile.has_key ("RAW", "CA")) { raw.ca_autocorrect = keyFile.get_boolean ("RAW", "CA" ); if (pedited) pedited->raw.caCorrection = true; }
if (keyFile.has_key ("RAW", "CARed")) { raw.cared = keyFile.get_double ("RAW", "CARed" ); if (pedited) pedited->raw.caRed = true; }
if (keyFile.has_key ("RAW", "CABlue")) { raw.cablue = keyFile.get_double ("RAW", "CABlue" ); if (pedited) pedited->raw.caBlue = true; }
- if (keyFile.has_key ("RAW", "HotDeadPixels")) { raw.hotdeadpix_filt = keyFile.get_boolean ("RAW", "HotDeadPixels" ); if (pedited) pedited->raw.hotDeadPixelFilter = true; }
+ // for compatibility to elder pp3 versions
+ if (keyFile.has_key ("RAW", "HotDeadPixels")) { raw.deadPixelFilter = raw.hotPixelFilter = keyFile.get_boolean ("RAW", "HotDeadPixels" ); if (pedited) pedited->raw.hotPixelFilter = pedited->raw.deadPixelFilter = true; }
+ if (keyFile.has_key ("RAW", "HotPixelFilter")) { raw.hotPixelFilter = keyFile.get_boolean ("RAW", "HotPixelFilter" ); if (pedited) pedited->raw.hotPixelFilter = true; }
+ if (keyFile.has_key ("RAW", "DeadPixelFilter")) { raw.deadPixelFilter = keyFile.get_boolean ("RAW", "DeadPixelFilter" ); if (pedited) pedited->raw.deadPixelFilter = true; }
+
if (keyFile.has_key ("RAW", "HotDeadPixelThresh")) { raw.hotdeadpix_thresh = keyFile.get_integer ("RAW", "HotDeadPixelThresh" ); if (pedited) pedited->raw.hotDeadPixelThresh = true; }
if (keyFile.has_key ("RAW", "PreExposure")) { raw.expos =keyFile.get_double("RAW", "PreExposure"); if (pedited) pedited->raw.exPos = true; }
if (keyFile.has_key ("RAW", "PrePreserv")) { raw.preser =keyFile.get_double("RAW", "PrePreserv"); if (pedited) pedited->raw.exPreser = true; }
@@ -2570,7 +2576,8 @@ bool ProcParams::operator== (const ProcParams& other) {
&& raw.ca_autocorrect == other.raw.ca_autocorrect
&& raw.cared == other.raw.cared
&& raw.cablue == other.raw.cablue
- && raw.hotdeadpix_filt == other.raw.hotdeadpix_filt
+ && raw.hotPixelFilter == other.raw.hotPixelFilter
+ && raw.deadPixelFilter == other.raw.deadPixelFilter
&& raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh
&& icm.input == other.icm.input
&& icm.toneCurve == other.icm.toneCurve
diff --git a/rtengine/procparams.h b/rtengine/procparams.h
index 8bbcdd695..68d16e45a 100644
--- a/rtengine/procparams.h
+++ b/rtengine/procparams.h
@@ -947,7 +947,8 @@ class RAWParams {
double expos;
double preser;
- bool hotdeadpix_filt;
+ bool hotPixelFilter;
+ bool deadPixelFilter;
int hotdeadpix_thresh;
};
diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h
index 809b914bd..441b26450 100755
--- a/rtengine/rawimage.h
+++ b/rtengine/rawimage.h
@@ -20,7 +20,6 @@
#define __RAWIMAGE_H
#include
-#include
#include "dcraw.h"
#include "imageio.h"
@@ -28,9 +27,9 @@ namespace rtengine {
struct badPix
{
- int x;
- int y;
- badPix( int xc, int yc ):x(xc),y(yc){}
+ uint16_t x;
+ uint16_t y;
+ badPix( uint16_t xc, uint16_t yc ):x(xc),y(yc){}
};
class PixelsMap{
@@ -66,12 +65,12 @@ public:
}
// set pixels from a list
- int set( std::list &bp)
+ int set( std::vector &bp)
{
- int totSet=0;
- for(std::list::iterator iter = bp.begin(); iter != bp.end(); iter++,totSet++)
+ for(std::vector::iterator iter = bp.begin(); iter != bp.end(); ++iter)
set( iter->x,iter->y);
- return totSet;
+
+ return bp.size();
}
void clear(){
@@ -156,6 +155,8 @@ public:
int get_thumbBPS(){ return thumb_load_raw ? 16 : 8; }
bool get_thumbSwap() const;
unsigned get_thumbLength(){ return thumb_length;}
+ bool zeroIsBad() {return zero_is_bad == 1 ? true : false;}
+
public:
// dcraw functions
void scale_colors(){ if(isXtrans()) clearXtransCblack( ); DCraw::scale_colors(); }
diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc
index a14df5ea8..6dccf8b7a 100644
--- a/rtengine/rawimagesource.cc
+++ b/rtengine/rawimagesource.cc
@@ -456,13 +456,14 @@ void RawImageSource::convertColorSpace(Imagefloat* image, ColorManagementParams
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-/* cfaCleanFromMap: correct raw pixels looking at the bitmap
+/* interpolateBadPixels: correct raw pixels looking at the bitmap
* takes into consideration if there are multiple bad pixels in the neighborhood
*/
-int RawImageSource::cfaCleanFromMap( PixelsMap &bitmapBads )
+int RawImageSource::interpolateBadPixels( PixelsMap &bitmapBads )
{
- float eps=1.0;
+ static const float eps=1.f;
int counter=0;
+#pragma omp parallel for reduction(+:counter) schedule(dynamic,16)
for( int row = 2; row < H-2; row++ ){
for(int col = 2; col weighting is 0.70710678
+ // For green channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
+ // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
+ // 0 0 0 0 0
+ // 0 1 0 1 0
+ // 0 0 0 0 0
+ // 0 1 0 1 0
+ // 0 0 0 0 0
+ for( int dx=-1;dx<=1;dx+=2){
+ if( bitmapBads.get(col+dx,row-1) || bitmapBads.get(col-dx,row+1))
+ continue;
+ float dirwt = 0.70710678f/( fabsf( rawData[row-1][col+dx]- rawData[row+1][col-dx])+eps);
+ wtdsum += dirwt * (rawData[row-1][col+dx] + rawData[row+1][col-dx]);
+ norm += dirwt;
+ }
+ } else {
+ // red and blue channel. Distance to center pixel is sqrt(8) => weighting is 0.35355339
+ // For red and blue channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
+ // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
+ // 1 0 0 0 1
+ // 0 0 0 0 0
+ // 0 0 0 0 0
+ // 0 0 0 0 0
+ // 1 0 0 0 1
+ for( int dx=-2;dx<=2;dx+=4){
+ if( bitmapBads.get(col+dx,row-2) || bitmapBads.get(col-dx,row+2))
+ continue;
+ float dirwt = 0.35355339f/( fabsf( rawData[row-2][col+dx]- rawData[row+2][col-dx])+eps);
+ wtdsum += dirwt * (rawData[row-2][col+dx] + rawData[row+2][col-dx]);
norm += dirwt;
}
}
- if (norm > 0.0){
- rawData[row][col]= wtdsum / norm;//gradient weighted average
+ // channel independent. Distance to center pixel is 2 => weighting is 0.5
+ // Additionally for all channel following pixels will be used for interpolation. Pixel to be interpolated is in center.
+ // 1 means that pixel is used in this step, if itself and his counterpart are not marked bad
+ // 0 0 1 0 0
+ // 0 0 0 0 0
+ // 1 0 0 0 1
+ // 0 0 0 0 0
+ // 0 0 1 0 0
+
+ // horizontal interpolation
+ if(!(bitmapBads.get(col-2,row) || bitmapBads.get(col+2,row))) {
+ float dirwt = 0.5f/( fabsf( rawData[row][col-2]- rawData[row][col+2])+eps);
+ wtdsum += dirwt * (rawData[row][col-2] + rawData[row][col+2]);
+ norm += dirwt;
+ }
+
+ // vertical interpolation
+ if(!(bitmapBads.get(col,row-2) || bitmapBads.get(col,row+2))) {
+ float dirwt = 0.5f/( fabsf( rawData[row-2][col]- rawData[row+2][col])+eps);
+ wtdsum += dirwt * (rawData[row-2][col] + rawData[row+2][col]);
+ norm += dirwt;
+ }
+
+ if (LIKELY(norm > 0.f)){ // This means, we found at least one pair of valid pixels in the steps above, likelyhood of this case is about 99.999%
+ rawData[row][col]= wtdsum / (2.f * norm);//gradient weighted average, Factor of 2.f is an optimization to avoid multiplications in former steps
counter++;
- } else {
- if (tot > 0.1) rawData[row][col] = sum/tot;//backup plan -- simple average
+ } else { //backup plan -- simple average. Same method for all channels. We could improve this, but it's really unlikely that this case happens
+ int tot = 0;
+ float sum = 0;
+ for( int dy=-2;dy<=2;dy+=2){
+ for( int dx=-2;dx<=2;dx+=2){
+ if(bitmapBads.get(col+dx,row+dy))
+ continue;
+ sum += rawData[row+dy][col+dx];
+ tot++;
+ }
+ }
+ if (tot > 0) {
+ rawData[row][col] = sum/tot;
+ counter ++;
+ }
}
}
}
- return counter;
+ return counter; // Number of interpolated pixels.
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -505,8 +564,10 @@ int RawImageSource::cfaCleanFromMap( PixelsMap &bitmapBads )
* (Taken from Emil Martinec idea)
* (Optimized by Ingo Weyrich 2013)
*/
-int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
+int RawImageSource::findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels )
{
+ float varthresh = (20.0*(thresh/100.0) + 1.0 );
+
// counter for dead or hot pixels
int counter=0;
@@ -528,7 +589,7 @@ int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
med3x3(rawData[iprev][jprev],rawData[iprev][j],rawData[iprev][jnext],
rawData[i][jprev],rawData[i][j],rawData[i][jnext],
rawData[inext][jprev],rawData[inext][j],rawData[inext][jnext],temp);
- cfablur[i*W+j] = fabs(rawData[i][j]-temp);
+ cfablur[i*W+j] = rawData[i][j]-temp;
}
}
#pragma omp for reduction(+:counter) schedule (dynamic,16)
@@ -540,16 +601,21 @@ int RawImageSource::findHotDeadPixel( PixelsMap &bpMap, float thresh)
for (int cc=0; cc < W; cc++,rrmWpcc++) {
//evaluate pixel for heat/death
float pixdev = cfablur[rrmWpcc];
+ if((!findDeadPixels) && pixdev <= 0)
+ continue;
+ if((!findHotPixels) && pixdev >= 0)
+ continue;
+ pixdev = fabsf(pixdev);
float hfnbrave = -pixdev;
int left=max(0,cc-2);
int right=min(W-1,cc+2);
for (int mm=top; mm<=bottom; mm++) {
int mmmWpnn = mm*W+left;
for (int nn=left; nn<=right; nn++,mmmWpnn++) {
- hfnbrave += cfablur[mmmWpnn];
+ hfnbrave += fabsf(cfablur[mmmWpnn]);
}
}
- if (pixdev * ((bottom-top+1)*(right-left+1)-1) > thresh*hfnbrave) {
+ if (pixdev * ((bottom-top+1)*(right-left+1)-1) > varthresh*hfnbrave) {
// mark the pixel as "bad"
bpMap.set(cc,rr);
counter++;
@@ -1015,7 +1081,23 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
if( rid && settings->verbose){
printf( "Subtracting Darkframe:%s\n",rid->get_filename().c_str());
}
- //copyOriginalPixels(ri, rid);
+
+ PixelsMap bitmapBads(W,H);
+ int totBP=0; // Hold count of bad pixels to correct
+
+ if(ri->zeroIsBad()) { // mark all pixels with value zero as bad, has to be called before FF and DF. dcraw sets this flag only for some cameras (mainly Panasonic and Leica)
+#pragma omp parallel for reduction(+:totBP)
+ for(int i=0;idata[i][j] == 0.f) {
+ bitmapBads.set(j,i);
+ totBP++;
+ }
+ }
+ if( settings->verbose) {
+ printf( "%d pixels with value zero marked as bad pixels\n",totBP);
+ }
+ }
//FLATFIELD start
Glib::ustring newFF = raw.ff_file;
@@ -1027,20 +1109,18 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
rif = ffm.searchFlatField( idata->getMake(), idata->getModel(),idata->getLens(),idata->getFocalLen(), idata->getFNumber(), idata->getDateTimeAsTS());
}
+
bool hasFlatField = (rif!=NULL);
if( hasFlatField && settings->verbose) {
printf( "Flat Field Correction:%s\n",rif->get_filename().c_str());
}
+
copyOriginalPixels(raw, ri, rid, rif);
//FLATFIELD end
-
-
- PixelsMap bitmapBads(W,H);
- int totBP=0; // Hold count of bad pixels to correct
- // Always correct camera badpixels
- std::list *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), std::string("") );
+ // Always correct camera badpixels from .badpixels file
+ std::vector *bp = dfm.getBadPixels( ri->get_maker(), ri->get_model(), idata->getSerialNumber() );
if( bp ){
totBP+=bitmapBads.set( *bp );
if( settings->verbose ){
@@ -1061,6 +1141,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
}
}
+
scaleColors( 0,0, W, H, raw);//+ + raw parameters for black level(raw.blackxx)
// Correct vignetting of lens profile
@@ -1081,20 +1162,17 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
defGain = 0.0;//log(initialGain) / log(2.0);
- if ( raw.hotdeadpix_filt>0 ) {
+ if ( raw.hotPixelFilter>0 || raw.deadPixelFilter>0) {
if (plistener) {
plistener->setProgressStr ("Hot/Dead Pixel Filter...");
plistener->setProgress (0.0);
}
- float varthresh = (20.0*((float)raw.hotdeadpix_thresh/100.0) + 1.0 );
- int nFound =findHotDeadPixel( bitmapBads, varthresh );
+ int nFound = findHotDeadPixels( bitmapBads, raw.hotdeadpix_thresh, raw.hotPixelFilter, raw.deadPixelFilter );
totBP += nFound;
if( settings->verbose && nFound>0){
printf( "Correcting %d hot/dead pixels found inside image\n",nFound );
}
}
- if( totBP )
- cfaCleanFromMap( bitmapBads );
// check if it is an olympus E camera, if yes, compute G channel pre-compensation factors
if ( ri->getSensorType()==ST_BAYER && (raw.bayersensor.greenthresh || (((idata->getMake().size()>=7 && idata->getMake().substr(0,7)=="OLYMPUS" && idata->getModel()[0]=='E') || (idata->getMake().size()>=9 && idata->getMake().substr(0,9)=="Panasonic")) && raw.bayersensor.method != RAWParams::BayerSensor::methodstring[ RAWParams::BayerSensor::vng4])) ) {
@@ -1136,6 +1214,10 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
green_equilibrate(0.01*(raw.bayersensor.greenthresh));
}
+
+ if( totBP )
+ interpolateBadPixels( bitmapBads );
+
if ( ri->getSensorType()==ST_BAYER && raw.bayersensor.linenoise >0 ) {
if (plistener) {
diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h
index 974e34f22..a5197d03a 100644
--- a/rtengine/rawimagesource.h
+++ b/rtengine/rawimagesource.h
@@ -217,8 +217,8 @@ class RawImageSource : public ImageSource {
void ddct8x8s(int isgn, float a[8][8]);
void processRawWhitepoint (float expos, float preser); // exposure before interpolation
- int cfaCleanFromMap( PixelsMap &bitmapBads );
- int findHotDeadPixel( PixelsMap &bpMap, float thresh);
+ int interpolateBadPixels( PixelsMap &bitmapBads );
+ int findHotDeadPixels( PixelsMap &bpMap, float thresh, bool findHotPixels, bool findDeadPixels );
void cfa_linedn (float linenoiselevel);//Emil's line denoise
void cfa_tile_denoise (fftwf_complex * fcfablox, int vblk, int hblk, int numblox_H, int numblox_W, float noisevar, float * rolloff );
diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc
index edf90ba7b..daa48f09a 100644
--- a/rtengine/refreshmap.cc
+++ b/rtengine/refreshmap.cc
@@ -118,7 +118,7 @@ LUMINANCECURVE, // EvLSaturation,
LUMINANCECURVE, // EvLaCurve,
LUMINANCECURVE, // EvLbCurve,
DEMOSAIC, // EvDemosaicMethod
-DARKFRAME, // EvPreProcessHotDeadPixel
+DARKFRAME, // EvPreProcessHotPixel
RGBCURVE, // EvSaturation,
RGBCURVE, // EvHSVEqualizerH,
RGBCURVE, // EvHSVEqualizerS,
@@ -318,8 +318,8 @@ RGBCURVE, //EvFilmSimulationEnabled
RGBCURVE, //EvFilmSimulationStrength
RGBCURVE, //EvFilmSimulationFilename
ALLNORAW, // EvDPDNLCurve
-ALLNORAW // EvDPDNsmet
-
+ALLNORAW, // EvDPDNsmet
+DARKFRAME // EvPreProcessDeadPixel
};
diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc
index 6aee8c56c..0126f4aef 100644
--- a/rtgui/paramsedited.cc
+++ b/rtgui/paramsedited.cc
@@ -317,7 +317,8 @@ void ParamsEdited::set (bool v) {
raw.caCorrection = v;
raw.caBlue = v;
raw.caRed = v;
- raw.hotDeadPixelFilter = v;
+ raw.hotPixelFilter = v;
+ raw.deadPixelFilter = v;
raw.hotDeadPixelThresh = v;
raw.darkFrame = v;
raw.dfAuto = v;
@@ -649,7 +650,8 @@ void ParamsEdited::initFrom (const std::vector
raw.caCorrection = raw.caCorrection && p.raw.ca_autocorrect == other.raw.ca_autocorrect;
raw.caRed = raw.caRed && p.raw.cared == other.raw.cared;
raw.caBlue = raw.caBlue && p.raw.cablue == other.raw.cablue;
- raw.hotDeadPixelFilter = raw.hotDeadPixelFilter && p.raw.hotdeadpix_filt == other.raw.hotdeadpix_filt;
+ raw.hotPixelFilter = raw.hotPixelFilter && p.raw.hotPixelFilter == other.raw.hotPixelFilter;
+ raw.deadPixelFilter = raw.deadPixelFilter && p.raw.deadPixelFilter == other.raw.deadPixelFilter;
raw.hotDeadPixelThresh = raw.hotDeadPixelThresh && p.raw.hotdeadpix_thresh == other.raw.hotdeadpix_thresh;
raw.darkFrame = raw.darkFrame && p.raw.dark_frame == other.raw.dark_frame;
raw.dfAuto = raw.dfAuto && p.raw.df_autoselect == other.raw.df_autoselect;
@@ -989,7 +991,8 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (raw.exPos) toEdit.raw.expos = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_LINEAR] ? toEdit.raw.expos + mods.raw.expos : mods.raw.expos;
if (raw.exPreser) toEdit.raw.preser = dontforceSet && options.baBehav[ADDSET_RAWEXPOS_PRESER] ? toEdit.raw.preser + mods.raw.preser : mods.raw.preser;
- if (raw.hotDeadPixelFilter) toEdit.raw.hotdeadpix_filt = mods.raw.hotdeadpix_filt;
+ if (raw.hotPixelFilter) toEdit.raw.hotPixelFilter = mods.raw.hotPixelFilter;
+ if (raw.deadPixelFilter) toEdit.raw.deadPixelFilter = mods.raw.deadPixelFilter;
if (raw.hotDeadPixelThresh) toEdit.raw.hotdeadpix_thresh = mods.raw.hotdeadpix_thresh;
if (raw.darkFrame) toEdit.raw.dark_frame = mods.raw.dark_frame;
if (raw.dfAuto) toEdit.raw.df_autoselect = mods.raw.df_autoselect;
@@ -1042,7 +1045,7 @@ bool RAWParamsEdited::XTransSensor::isUnchanged() const {
}
bool RAWParamsEdited::isUnchanged() const {
- return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && caCorrection && caRed && caBlue && hotDeadPixelFilter && hotDeadPixelThresh && darkFrame
+ return bayersensor.isUnchanged() && xtranssensor.isUnchanged() && caCorrection && caRed && caBlue && hotPixelFilter && deadPixelFilter && hotDeadPixelThresh && darkFrame
&& dfAuto && ff_file && ff_AutoSelect && ff_BlurRadius && ff_BlurType && exPos && exPreser && ff_AutoClipControl && ff_clipControl;
}
diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h
index 4fb6c6617..2d43cfe3d 100644
--- a/rtgui/paramsedited.h
+++ b/rtgui/paramsedited.h
@@ -536,7 +536,8 @@ class RAWParamsEdited {
bool caCorrection;
bool caRed;
bool caBlue;
- bool hotDeadPixelFilter;
+ bool hotPixelFilter;
+ bool deadPixelFilter;
bool hotDeadPixelThresh;
bool darkFrame;
bool dfAuto;
diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc
index c4e35af9e..4888e5675 100644
--- a/rtgui/partialpastedlg.cc
+++ b/rtgui/partialpastedlg.cc
@@ -97,7 +97,8 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) {
raw_ca_autocorrect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_AUTO")));
raw_cared = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CARED")));
raw_cablue = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWCACORR_CABLUE")));
- raw_hotdeadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTDEADPIXFILT")));
+ raw_hotpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_HOTPIXFILT")));
+ raw_deadpix_filt = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_DEADPIXFILT")));
raw_linenoise = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_LINEDENOISE")));
raw_greenthresh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_PREPROCESS_GREENEQUIL")));
raw_method = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAW_DMETHOD")));
@@ -190,7 +191,8 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) {
vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0);
vboxes[6]->pack_start (*raw_linenoise, Gtk::PACK_SHRINK, 2);
vboxes[6]->pack_start (*raw_greenthresh, Gtk::PACK_SHRINK, 2);
- vboxes[6]->pack_start (*raw_hotdeadpix_filt, Gtk::PACK_SHRINK, 2);
+ vboxes[6]->pack_start (*raw_hotpix_filt, Gtk::PACK_SHRINK, 2);
+ vboxes[6]->pack_start (*raw_deadpix_filt, Gtk::PACK_SHRINK, 2);
vboxes[6]->pack_start (*Gtk::manage (new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 0);
vboxes[6]->pack_start (*raw_expos, Gtk::PACK_SHRINK, 2);
vboxes[6]->pack_start (*raw_preser, Gtk::PACK_SHRINK, 2);
@@ -307,7 +309,8 @@ PartialPasteDlg::PartialPasteDlg (Glib::ustring title) {
raw_ca_autocorrectConn = raw_ca_autocorrect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
raw_caredConn = raw_cared->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
raw_cablueConn = raw_cablue->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
- raw_hotdeadpix_filtConn = raw_hotdeadpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
+ raw_hotpix_filtConn = raw_hotpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
+ raw_deadpix_filtConn = raw_deadpix_filt->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
raw_linenoiseConn = raw_linenoise->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
raw_greenthreshConn = raw_greenthresh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
df_fileConn = df_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true));
@@ -378,7 +381,8 @@ void PartialPasteDlg::rawToggled () {
raw_ca_autocorrectConn.block (true);
raw_caredConn.block (true);
raw_cablueConn.block (true);
- raw_hotdeadpix_filtConn.block (true);
+ raw_hotpix_filtConn.block (true);
+ raw_deadpix_filtConn.block (true);
raw_linenoiseConn.block (true);
raw_greenthreshConn.block (true);
df_fileConn.block (true);
@@ -403,7 +407,8 @@ void PartialPasteDlg::rawToggled () {
raw_ca_autocorrect->set_active (raw->get_active ());
raw_cared->set_active (raw->get_active ());
raw_cablue->set_active (raw->get_active ());
- raw_hotdeadpix_filt->set_active (raw->get_active ());
+ raw_hotpix_filt->set_active (raw->get_active ());
+ raw_deadpix_filt->set_active (raw->get_active ());
raw_linenoise->set_active (raw->get_active ());
raw_greenthresh->set_active (raw->get_active ());
df_file->set_active (raw->get_active ());
@@ -426,7 +431,8 @@ void PartialPasteDlg::rawToggled () {
raw_ca_autocorrectConn.block (false);
raw_caredConn.block (false);
raw_cablueConn.block (false);
- raw_hotdeadpix_filtConn.block (false);
+ raw_hotpix_filtConn.block (false);
+ raw_deadpix_filtConn.block (false);
raw_linenoiseConn.block (false);
raw_greenthreshConn.block (false);
df_fileConn.block (false);
@@ -688,7 +694,9 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dstPP, Param
if (!raw_ca_autocorrect->get_active ()) filterPE.raw.caCorrection = falsePE.raw.caCorrection;
if (!raw_cared->get_active ()) filterPE.raw.caRed = falsePE.raw.caRed;
if (!raw_cablue->get_active ()) filterPE.raw.caBlue = falsePE.raw.caBlue;
- if (!raw_hotdeadpix_filt->get_active ()) { filterPE.raw.hotDeadPixelFilter = falsePE.raw.hotDeadPixelFilter;
+ if (!raw_hotpix_filt->get_active ()) { filterPE.raw.hotPixelFilter = falsePE.raw.hotPixelFilter;
+ filterPE.raw.hotDeadPixelThresh = falsePE.raw.hotDeadPixelThresh; }
+ if (!raw_deadpix_filt->get_active ()) { filterPE.raw.deadPixelFilter = falsePE.raw.deadPixelFilter;
filterPE.raw.hotDeadPixelThresh = falsePE.raw.hotDeadPixelThresh; }
if (!df_file->get_active ()) filterPE.raw.darkFrame = falsePE.raw.darkFrame;
if (!df_AutoSelect->get_active ()) filterPE.raw.dfAuto = falsePE.raw.dfAuto;
diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h
index 64750523a..d546b6624 100644
--- a/rtgui/partialpastedlg.h
+++ b/rtgui/partialpastedlg.h
@@ -94,7 +94,8 @@ class PartialPasteDlg : public Gtk::Dialog {
Gtk::CheckButton* raw_ca_autocorrect;
Gtk::CheckButton* raw_cared;
Gtk::CheckButton* raw_cablue;
- Gtk::CheckButton* raw_hotdeadpix_filt;
+ Gtk::CheckButton* raw_hotpix_filt;
+ Gtk::CheckButton* raw_deadpix_filt;
Gtk::CheckButton* raw_linenoise;
Gtk::CheckButton* raw_greenthresh;
Gtk::CheckButton* raw_method;
@@ -121,7 +122,7 @@ class PartialPasteDlg : public Gtk::Dialog {
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn;
sigc::connection exifchConn, iptcConn, icmConn, gamcsconn;
sigc::connection df_fileConn, df_AutoSelectConn, ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn, ff_ClipControlConn;
- sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotdeadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; //,raw_all_enhanceConn
+ sigc::connection raw_caredConn, raw_cablueConn, raw_ca_autocorrectConn, raw_hotpix_filtConn, raw_deadpix_filtConn, raw_linenoiseConn, raw_greenthreshConn, raw_ccStepsConn, raw_methodConn, raw_dcb_iterationsConn, raw_lmmse_iterationsConn, raw_dcb_enhanceConn, raw_exposConn, raw_preserConn, raw_blackConn; //,raw_all_enhanceConn
public:
PartialPasteDlg (Glib::ustring title);
diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc
index f965f2492..80311a2d2 100644
--- a/rtgui/preprocess.cc
+++ b/rtgui/preprocess.cc
@@ -26,54 +26,86 @@ using namespace rtengine::procparams;
PreProcess::PreProcess () : FoldableToolPanel(this)
{
- hotDeadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTDEADPIXFILT"))));
- hotDeadPixel->set_tooltip_markup (M("TP_PREPROCESS_HOTDEADPIXFILT_TOOLTIP"));
-
- pack_start( *hotDeadPixel, Gtk::PACK_SHRINK, 4);
-
- hdpixelconn = hotDeadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotDeadPixelChanged), true);
+
+ Gtk::HBox* hotdeadPixel = Gtk::manage( new Gtk::HBox () );
+ hotdeadPixel->set_spacing(4);
+ hotPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_HOTPIXFILT"))));
+ deadPixel = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_DEADPIXFILT"))));
+
+ hotPixel->set_tooltip_markup (M("TP_PREPROCESS_HOTPIXFILT_TOOLTIP"));
+ deadPixel->set_tooltip_markup (M("TP_PREPROCESS_DEADPIXFILT_TOOLTIP"));
+
+ hotdeadPixel->pack_start( *hotPixel, Gtk::PACK_SHRINK);
+ hotdeadPixel->pack_start( *deadPixel, Gtk::PACK_SHRINK, 0);
+ pack_start(*hotdeadPixel, Gtk::PACK_SHRINK, 0);
+// hotdeadPixel->show();
+ hpixelconn = hotPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotPixelChanged), true);
+ dpixelconn = deadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::deadPixelChanged), true);
}
void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited)
{
disableListener ();
- hdpixelconn.block (true);
-
+ hpixelconn.block (true);
+ dpixelconn.block (true);
if(pedited ){
- hotDeadPixel->set_inconsistent (!pedited->raw.hotDeadPixelFilter);
+ hotPixel->set_inconsistent (!pedited->raw.hotPixelFilter);
+ deadPixel->set_inconsistent (!pedited->raw.deadPixelFilter);
}
- lastHot = pp->raw.hotdeadpix_filt;
+ lastHot = pp->raw.hotPixelFilter;
+ lastDead = pp->raw.deadPixelFilter;
+ hotPixel->set_active (pp->raw.hotPixelFilter);
+ deadPixel->set_active (pp->raw.deadPixelFilter);
- hotDeadPixel->set_active (pp->raw.hotdeadpix_filt);
-
- hdpixelconn.block (false);
+ hpixelconn.block (false);
+ dpixelconn.block (false);
enableListener ();
}
void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedited)
{
- pp->raw.hotdeadpix_filt = hotDeadPixel->get_active();
+ pp->raw.hotPixelFilter = hotPixel->get_active();
+ pp->raw.deadPixelFilter = deadPixel->get_active();
if (pedited) {
- pedited->raw.hotDeadPixelFilter = !hotDeadPixel->get_inconsistent();
+ pedited->raw.hotPixelFilter = !hotPixel->get_inconsistent();
+ pedited->raw.deadPixelFilter = !deadPixel->get_inconsistent();
}
}
-void PreProcess::hotDeadPixelChanged ()
+void PreProcess::hotPixelChanged ()
{
if (batchMode) {
- if (hotDeadPixel->get_inconsistent()) {
- hotDeadPixel->set_inconsistent (false);
- hdpixelconn.block (true);
- hotDeadPixel->set_active (false);
- hdpixelconn.block (false);
+ if (hotPixel->get_inconsistent()) {
+ hotPixel->set_inconsistent (false);
+ hpixelconn.block (true);
+ hotPixel->set_active (false);
+ hpixelconn.block (false);
}
else if (lastHot)
- hotDeadPixel->set_inconsistent (true);
+ hotPixel->set_inconsistent (true);
- lastHot = hotDeadPixel->get_active ();
+ lastHot = hotPixel->get_active ();
}
if (listener)
- listener->panelChanged (EvPreProcessHotDeadPixel, hotDeadPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED"));
+ listener->panelChanged (EvPreProcessHotPixel, hotPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED"));
+}
+
+void PreProcess::deadPixelChanged ()
+{
+ if (batchMode) {
+ if (deadPixel->get_inconsistent()) {
+ deadPixel->set_inconsistent (false);
+ dpixelconn.block (true);
+ deadPixel->set_active (false);
+ dpixelconn.block (false);
+ }
+ else if (lastDead)
+ deadPixel->set_inconsistent (true);
+
+ lastDead = deadPixel->get_active ();
+ }
+ if (listener)
+ listener->panelChanged (EvPreProcessDeadPixel, deadPixel->get_active()?M("GENERAL_ENABLED"):M("GENERAL_DISABLED"));
}
diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h
index 116cb585e..215f4becb 100644
--- a/rtgui/preprocess.h
+++ b/rtgui/preprocess.h
@@ -27,10 +27,11 @@
class PreProcess : public ToolParamBlock, /*public AdjusterListener,*/ public FoldableToolPanel {
protected:
-
- Gtk::CheckButton* hotDeadPixel;
- bool lastHot;
- sigc::connection hdpixelconn;
+ Gtk::CheckButton* hotPixel;
+ Gtk::CheckButton* deadPixel;
+ bool lastHot,lastDead;
+ sigc::connection hpixelconn;
+ sigc::connection dpixelconn;
public:
@@ -41,7 +42,8 @@ class PreProcess : public ToolParamBlock, /*public AdjusterListener,*/ public Fo
//void setBatchMode (bool batchMode);
//void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
- void hotDeadPixelChanged();
+ void hotPixelChanged();
+ void deadPixelChanged();
//void adjusterChanged (Adjuster* a, double newval);
//void setAdjusterBehavior (bool linedenoiseadd, bool greenequiladd);