From 40c936504efd2dfcd18709a576675ccf18d0fa64 Mon Sep 17 00:00:00 2001 From: Emil Martinec Date: Mon, 17 Jan 2011 21:07:59 -0600 Subject: [PATCH] Flatfield tool. --- CMakeLists.txt | 2 +- rtdata/languages/default | 35 ++++- rtdata/profiles/crisp.pp3 | 4 + rtdata/profiles/default.pp3 | 4 + rtdata/profiles/neutral.pp3 | 4 + rtengine/CMakeLists.txt | 2 +- rtengine/init.cc | 2 + rtengine/procevents.h | 7 +- rtengine/procparams.cc | 18 ++- rtengine/procparams.h | 11 +- rtengine/rawimage.h | 1 + rtengine/rawimagesource.cc | 252 +++++++++++++++++++++++++++++------- rtengine/rawimagesource.h | 5 +- rtengine/refreshmap.cc | 8 +- rtengine/refreshmap.h | 1 + rtengine/settings.h | 3 +- rtgui/filebrowser.cc | 52 +++++++- rtgui/filebrowser.h | 3 + rtgui/options.cc | 11 +- rtgui/paramsedited.cc | 16 ++- rtgui/paramsedited.h | 4 + rtgui/partialpastedlg.cc | 181 +++++++++++++++++++++----- rtgui/partialpastedlg.h | 27 +++- rtgui/preferences.cc | 67 ++++++++-- rtgui/preferences.h | 6 +- rtgui/preprocess.cc | 211 +++++++++++++++++++++++++++++- rtgui/preprocess.h | 40 +++++- rtgui/toolpanelcoord.cc | 40 ++++++ rtgui/toolpanelcoord.h | 18 ++- 29 files changed, 914 insertions(+), 121 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index faa86ff49..989974143 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ endif (APPLE) option (BUILD_SHARED "Build rawtherapee with shared libraries" OFF) option (WITH_RAWZOR "Build with Rawzor support" OFF) -option (WITH_MYFILE_MMAP "Build using memory mapped file" OFF) +option (WITH_MYFILE_MMAP "Build using memory mapped file" ON) option (OPTION_OMP "Build with OpenMP support" ON) # set install directories diff --git a/rtdata/languages/default b/rtdata/languages/default index 9e3acb996..a1fbbcdc5 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -49,6 +49,7 @@ FILEBROWSER_ADDDELTEMPLATE;Add/Del templates... FILEBROWSER_APPLYPROFILE;Apply profile FILEBROWSER_ARRANGEMENTHINT;Change between vertical/horizontal alignment of thumbnails FILEBROWSER_AUTODARKFRAME;Auto dark frame +FILEBROWSER_AUTOFLATFIELD;Auto flat field FILEBROWSER_BROWSEPATHBUTTONHINT;Click to browse to the chosen path FILEBROWSER_BROWSEPATHHINT;Type path to browse (Ctrl-Enter in File Browser) FILEBROWSER_CLEARPROFILE;Clear profile @@ -64,6 +65,7 @@ FILEBROWSER_EXIFFILTERLABEL;Exif Filter FILEBROWSER_EXIFFILTERSETTINGS;Setup FILEBROWSER_EXIFFILTERSETTINGSHINT;Change settings of the exif filter FILEBROWSER_MOVETODARKFDIR;Move to dark frames directory +FILEBROWSER_MOVETOFLATFIELDDIR;Move to flat fields directory FILEBROWSER_NEW_NAME;New name: FILEBROWSER_PARTIALPASTEPROFILE;Partial paste FILEBROWSER_PASTEPROFILE;Paste profile @@ -88,6 +90,7 @@ FILEBROWSER_PROCESSINGSETTINGSHINT;Set the file format and output directory FILEBROWSER_RENAMEDLGLABEL;Rename file FILEBROWSER_RENAMEDLGMSG;Rename file "%1" to: FILEBROWSER_SELECTDARKFRAME;Select dark frame... +FILEBROWSER_SELECTFLATFIELD;Select flat field... FILEBROWSER_SHOWDIRHINT;Show all images of the directory D FILEBROWSER_SHOWEXIFINFO;Show EXIF info i FILEBROWSER_SHOWQUEUEHINT;Show content of the processing queue @@ -148,7 +151,11 @@ HISTORY_MSG_105;Defringing HISTORY_MSG_106;Defringing Radius HISTORY_MSG_107;Defringing Threshold HISTORY_MSG_108;Resize bounding box -HISTORY_MSG_109;Resizing applies to +HISTORY_MSG_109;Resizing applies to +HISTORY_MSG_110;Flat Field File +HISTORY_MSG_111;Flat Field Auto Select +HISTORY_MSG_112;Flat Field Blur Radius +HISTORY_MSG_113;Flat Field Blur Type HISTORY_MSG_10;Shadow Compression HISTORY_MSG_11;Tone Curve HISTORY_MSG_12;Auto Exposure @@ -401,10 +408,17 @@ PARTIALPASTE_COLORMIXER;Color mixer PARTIALPASTE_COLORSHIFT;Color shift PARTIALPASTE_COMPOSITIONGROUP;Composition settings PARTIALPASTE_CROP;Crop +PARTIALPASTE_DARKFRAMEFILE;Dark Frame File +PARTIALPASTE_DARKFRAMEAUTOSELECT;Dark Frame Auto Select PARTIALPASTE_DIALOGLABEL;Partial paste processing profile PARTIALPASTE_DISTORTION;Distortion correction +PARTIALPASTE_EVERYTHING;Everything PARTIALPASTE_EXIFCHANGES;Changes to exif data PARTIALPASTE_EXPOSURE;Exposure +PARTIALPASTE_FLATFIELDFILE;Flat field (FF) File +PARTIALPASTE_FLATFIELDBLURRADIUS;FF Blur Radius +PARTIALPASTE_FLATFIELDBLURTYPE;FF Blur Type +PARTIALPASTE_FLATFIELDAUTOSELECT;FF Auto Select PARTIALPASTE_HLRECOVERY;Highlight recovery PARTIALPASTE_HLRECOVERYAMOUNT;Highlight recovery amount PARTIALPASTE_HLRECOVERYTHRESHOLD;Highlight recovery threshold @@ -415,12 +429,13 @@ PARTIALPASTE_LENSGROUP;Lens related settings PARTIALPASTE_LUMADENOISE;Luminance noise reduction PARTIALPASTE_LUMINANCEGROUP;Luminance related settings PARTIALPASTE_METAICMGROUP;Metadata/ICM settings +PARTIALPASTE_RAWGROUP;Raw settings PARTIALPASTE_RESIZE;Resize PARTIALPASTE_ROTATION;Rotation PARTIALPASTE_SHADOWSHIGHLIGHTS;Shadows/Highlights PARTIALPASTE_SHARPENING;Sharpening PARTIALPASTE_VIGNETTING;Vignetting correction -PARTIALPASTE_WHITEBALANCE;White balance +PARTIALPASTE_WHITEBALANCE;White balance POPUPBUTTON_SELECTOPTIONHINT;RMB to change option PREFERENCES_ADD;ADD PREFERENCES_APPLNEXTSTARTUP;restart required @@ -446,6 +461,18 @@ PREFERENCES_CLIPPINGIND;Clipping indication PREFERENCES_CMETRICINTENT;Colorimetric Intent PREFERENCES_CUTOVERLAYBRUSH;Cut overlay brush PREFERENCES_DARKFRAME;Dark frame +PREFERENCES_DARKFRAMEFOUND;Found +PREFERENCES_DARKFRAMESHOTS;shots +PREFERENCES_DARKFRAMETEMPLATES;templates +PREFERENCES_FLATFIELD;Flat Field +PREFERENCES_FLATFIELDFOUND;Found +PREFERENCES_FLATFIELDSHOTS;shots +PREFERENCES_FLATFIELDTEMPLATES;templates +PREFERENCES_FLATFIELDFILE;Flat Field File +PREFERENCES_FLATFIELDBLURRADIUS;Flat Field Blur Radius +PREFERENCES_FLATFIELDBLURTYPE;Flat Field Blur Type +PREFERENCES_FLATFIELDAUTOSELECT;Flat Field Auto Select +PREFERENCES_FLATFIELDSDIR;Flat Fields directory PREFERENCES_DATEFORMAT;Date Format PREFERENCES_DATEFORMATHINT;You can use the following formatting strings:\n%y : year\n%m : month\n%d : day\n\nFor example, the hungarian date format is:\n%y/%m/%d PREFERENCES_DCBENHANCE;Apply DCB enhancement step @@ -718,6 +745,10 @@ TP_PERSPECTIVE_LABEL;Perspective TP_PERSPECTIVE_VERTICAL;Vertical TP_PREPROCESS_DARKFRAME;Dark frame TP_PREPROCESS_DFAUTOSELECT;Auto selection +TP_PREPROCESS_FLATFIELDFILE;Flat Field File +TP_PREPROCESS_FLATFIELDBLURRADIUS;Flat Field Blur Radius +TP_PREPROCESS_FLATFIELDBLURTYPE;Flat Field Blur Type +TP_PREPROCESS_FLATFIELDAUTOSELECT;Flat Field Auto Select TP_RAWPANEL_DEMOSAICING;Demosaicing TP_RAWPANEL_PREPROCESSING;Preprocessing TP_RESIZE_APPLIESTO;Applies to: diff --git a/rtdata/profiles/crisp.pp3 b/rtdata/profiles/crisp.pp3 index a6ffd6fdb..d95bcd2e7 100644 --- a/rtdata/profiles/crisp.pp3 +++ b/rtdata/profiles/crisp.pp3 @@ -169,6 +169,10 @@ Mult4=0 [RAW] DarkFrame= DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield CA=false HotDeadPixels=false LineDenoise=0 diff --git a/rtdata/profiles/default.pp3 b/rtdata/profiles/default.pp3 index 30f2d7fd7..3f2c0a5c2 100644 --- a/rtdata/profiles/default.pp3 +++ b/rtdata/profiles/default.pp3 @@ -169,6 +169,10 @@ Mult4=0 [RAW] DarkFrame= DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield CA=false HotDeadPixels=false LineDenoise=0 diff --git a/rtdata/profiles/neutral.pp3 b/rtdata/profiles/neutral.pp3 index aa550bf00..31d0b85a7 100644 --- a/rtdata/profiles/neutral.pp3 +++ b/rtdata/profiles/neutral.pp3 @@ -168,6 +168,10 @@ Mult4=0 [RAW] DarkFrame= DarkFrameAuto=false +FlatFieldFile= +FlatFieldAutoSelect=false +FlatFieldBlurRadius=32 +FlatFieldBlurType=Area Flatfield CA=false HotDeadPixels=false LineDenoise=0 diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 998f6b9f5..f60b9e11e 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -7,7 +7,7 @@ link_directories (${CMAKE_CURRENT_SOURCE_DIR}/../rtexif ${EXTRA_LIBDIR} ${GTHREA ${GOBJECT_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS}) -set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc dcraw.cc iccstore.cc dfmanager.cc rawimage.cc +set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc dcraw.cc iccstore.cc dfmanager.cc ffmanager.cc rawimage.cc image8.cc image16.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc loadinitial.cc procparams.cc rawimagesource.cc shmap.cc simpleprocess.cc refreshmap.cc stdimagesource.cc myfile.cc iccjpeg.c hlmultipliers.cc improccoordinator.cc diff --git a/rtengine/init.cc b/rtengine/init.cc index 40a2a1ba5..51a411cb0 100644 --- a/rtengine/init.cc +++ b/rtengine/init.cc @@ -22,6 +22,7 @@ #include #include #include +#include #include namespace rtengine { @@ -41,6 +42,7 @@ int init (const Settings* s) { delete lcmsMutex; lcmsMutex = new Glib::Mutex; dfm.init( s->darkFramesPath ); + ffm.init( s->flatFieldsPath ); return 0; } diff --git a/rtengine/procevents.h b/rtengine/procevents.h index 39736905a..73476665b 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -131,7 +131,12 @@ enum ProcEvent { EvDefringeThreshold=106, EvResizeBoundingBox=107, EvResizeAppliesTo=108, - NUMOFEVENTS=109 + EvFlatFieldFile=109, + EvFlatFieldAutoSelect=110, + EvFlatFieldBlurRadius=111, + EvFlatFieldBlurType=112, + + NUMOFEVENTS=113 }; } #endif diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 7ea5ed1be..aa03ec936 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -29,6 +29,7 @@ namespace rtengine { namespace procparams { const char *RAWParams::methodstring[RAWParams::numMethods]={"eahd", "hphd", "vng4", "dcb", "amaze", "ahd", "fast" }; +const char *RAWParams::ff_BlurTypestring[RAWParams::numFlatFileBlurTypes]={/*"Parametric",*/ "Area Flatfield", "Vertical Flatfield", "Horizontal Flatfield", "V+H Flatfield"}; ProcParams::ProcParams () { @@ -201,6 +202,9 @@ void ProcParams::setDefaults () { hsvequalizer.hue[i] = 0; } raw.df_autoselect = false; + raw.ff_AutoSelect = false; + raw.ff_BlurRadius = 32; + raw.ff_BlurType = RAWParams::ff_BlurTypestring[RAWParams::area_ff]; raw.cared = 0; raw.cablue = 0; raw.ca_autocorrect = false; @@ -431,6 +435,10 @@ int ProcParams::save (Glib::ustring fname) const { // save RAW parameters keyFile.set_string ("RAW", "DarkFrame", raw.dark_frame ); keyFile.set_boolean ("RAW", "DarkFrameAuto", raw.df_autoselect ); + keyFile.set_string ("RAW", "FlatFieldFile", raw.ff_file ); + keyFile.set_boolean ("RAW", "FlatFieldAutoSelect", raw.ff_AutoSelect ); + keyFile.set_integer ("RAW", "FlatFieldBlurRadius", raw.ff_BlurRadius ); + keyFile.set_string ("RAW", "FlatFieldBlurType", raw.ff_BlurType ); keyFile.set_boolean ("RAW", "CA", raw.ca_autocorrect ); keyFile.set_double ("RAW", "CARed", raw.cared ); keyFile.set_double ("RAW", "CABlue", raw.cablue ); @@ -754,6 +762,10 @@ if (keyFile.has_group ("HSV Equalizer")) { if (keyFile.has_group ("RAW")) { if (keyFile.has_key ("RAW", "DarkFrame")) raw.dark_frame = keyFile.get_string ("RAW", "DarkFrame" ); if (keyFile.has_key ("RAW", "DarkFrameAuto")) raw.df_autoselect = keyFile.get_boolean ("RAW", "DarkFrameAuto" ); + if (keyFile.has_key ("RAW", "FlatFieldFile")) raw.ff_file = keyFile.get_string ("RAW", "FlatFieldFile" ); + if (keyFile.has_key ("RAW", "FlatFieldAutoSelect")) raw.ff_AutoSelect = keyFile.get_boolean ("RAW", "FlatFieldAutoSelect" ); + if (keyFile.has_key ("RAW", "FlatFieldBlurRadius")) raw.ff_BlurRadius = keyFile.get_integer ("RAW", "FlatFieldBlurRadius" ); + if (keyFile.has_key ("RAW", "FlatFieldBlurType")) raw.ff_BlurType = keyFile.get_string ("RAW", "FlatFieldBlurType" ); if (keyFile.has_key ("RAW", "CA")) raw.ca_autocorrect = keyFile.get_boolean ("RAW", "CA" ); if (keyFile.has_key ("RAW", "CARed")) raw.cared = keyFile.get_double ("RAW", "CARed" ); if (keyFile.has_key ("RAW", "CABlue")) raw.cablue = keyFile.get_double ("RAW", "CABlue" ); @@ -949,7 +961,11 @@ bool ProcParams::operator== (const ProcParams& other) { && resize.width == other.resize.width && resize.height == other.resize.height && raw.dark_frame == other.raw.dark_frame - && raw.df_autoselect == other.raw.df_autoselect + && raw.df_autoselect == other.raw.df_autoselect + && raw.ff_file == other.raw.ff_file + && raw.ff_AutoSelect == other.raw.ff_AutoSelect + && raw.ff_BlurRadius == other.raw.ff_BlurRadius + && raw.ff_BlurType == other.raw.ff_BlurType && raw.dcb_enhance == other.raw.dcb_enhance && raw.dcb_iterations == other.raw.dcb_iterations && raw.ccSteps == other.raw.ccSteps diff --git a/rtengine/procparams.h b/rtengine/procparams.h index d5b405148..582143a87 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -389,10 +389,19 @@ class RAWParams { numMethods }; // This MUST be the last enum static const char *methodstring[numMethods]; - + enum eFlatFileBlurType{/*parametric,*/area_ff,v_ff,h_ff,vh_ff, + numFlatFileBlurTypes }; // This MUST be the last enum + static const char *ff_BlurTypestring[numFlatFileBlurTypes]; + Glib::ustring dark_frame; bool df_autoselect; + + Glib::ustring ff_file; + bool ff_AutoSelect; + int ff_BlurRadius; + Glib::ustring ff_BlurType; + bool ca_autocorrect; double cared; double cablue; diff --git a/rtengine/rawimage.h b/rtengine/rawimage.h index 65a989663..c33d23887 100644 --- a/rtengine/rawimage.h +++ b/rtengine/rawimage.h @@ -123,6 +123,7 @@ public: double get_ISOspeed() const {return iso_speed;} double get_shutter() const {return shutter; } + double get_aperture() const {return aperture; } time_t get_timestamp() const { return timestamp;} int get_rotateDegree() const { return rotate_deg;} const std::string get_maker() const { return std::string(make); } diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index efe8af1ae..6b8be2c36 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -952,14 +953,32 @@ void RawImageSource::preprocess (const RAWParams &raw) RawImage *rid=NULL; if (!raw.df_autoselect) { if( raw.dark_frame.size()>0) - rid = dfm.searchDarkFrame( raw.dark_frame ); - }else{ + rid = dfm.searchDarkFrame( raw.dark_frame ); + } else { rid = dfm.searchDarkFrame( ri->get_maker(), ri->get_model(), ri->get_ISOspeed(), ri->get_shutter(), ri->get_timestamp()); } if( rid && settings->verbose){ printf( "Subtracting Darkframe:%s\n",rid->get_filename().c_str()); } - copyOriginalPixels(ri, rid); + //copyOriginalPixels(ri, rid); + + //FLATFIELD start + Glib::ustring newFF = raw.ff_file; + RawImage *rif=NULL; + if (!raw.ff_AutoSelect) { + if( raw.ff_file.size()>0) + rif = ffm.searchFlatField( raw.ff_file ); + } else { + rif = ffm.searchFlatField( ri->get_maker(), ri->get_model(), ri->get_ISOspeed(), ri->get_shutter(), ri->get_aperture(), ri->get_timestamp()); + } + if( rif && 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 @@ -1108,49 +1127,186 @@ void RawImageSource::demosaic(const RAWParams &raw) } + /* Copy original pixel data and - * subtract dark frame (if present) from current image + * subtract dark frame (if present) from current image and apply flat field correction (if present) */ -void RawImageSource::copyOriginalPixels(RawImage *src, RawImage *riDark ) +void RawImageSource::copyOriginalPixels(const RAWParams &raw, RawImage *src, RawImage *riDark, RawImage *riFlatFile ) { if (ri->isBayer()) { if (!rawData) rawData = allocArray< unsigned short >(W,H); - if (riDark && W == riDark->get_width() && H == riDark->get_height()) { - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][col] = MAX (src->data[row][col]+ri->get_black() - riDark->data[row][col], 0); + + if (ri->isBayer()) { + if (!rawData) + rawData = allocArray< unsigned short >(W,H); + if (riDark && W == riDark->get_width() && H == riDark->get_height()) { + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][col] = MAX (src->data[row][col]+ri->get_black() - riDark->data[row][col], 0); + } + } + }else{ + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][col] = src->data[row][col]; + } } } }else{ - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][col] = src->data[row][col]; + if (!rawData) + rawData = allocArray< unsigned short >(3*W,H); + if (riDark && W == riDark->get_width() && H == riDark->get_height()) { + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][3*col+0] = MAX (src->data[row][3*col+0]+ri->get_black() - riDark->data[row][3*col+0], 0); + rawData[row][3*col+1] = MAX (src->data[row][3*col+1]+ri->get_black() - riDark->data[row][3*col+1], 0); + rawData[row][3*col+2] = MAX (src->data[row][3*col+2]+ri->get_black() - riDark->data[row][3*col+2], 0); + } + } + }else{ + for (int row = 0; row < H; row++) { + for (int col = 0; col < W; col++) { + rawData[row][3*col+0] = src->data[row][3*col+0]; + rawData[row][3*col+1] = src->data[row][3*col+1]; + rawData[row][3*col+2] = src->data[row][3*col+2]; + } } } } - }else{ - if (!rawData) - rawData = allocArray< unsigned short >(3*W,H); - if (riDark && W == riDark->get_width() && H == riDark->get_height()) { - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][3*col+0] = MAX (src->data[row][3*col+0]+ri->get_black() - riDark->data[row][3*col+0], 0); - rawData[row][3*col+1] = MAX (src->data[row][3*col+1]+ri->get_black() - riDark->data[row][3*col+1], 0); - rawData[row][3*col+2] = MAX (src->data[row][3*col+2]+ri->get_black() - riDark->data[row][3*col+2], 0); + + + if (riFlatFile && W == riFlatFile->get_width() && H == riFlatFile->get_height()) { + + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + float (*cfablur); + cfablur = (float (*)) calloc (H*W, sizeof *cfablur); +//#define BS 32 + int BS = raw.ff_BlurRadius; + if (BS&1) BS++; + + //function call to cfabloxblur + if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::v_ff]) + cfaboxblur(riFlatFile, cfablur, 2*BS, 0); + else if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::h_ff]) + cfaboxblur(riFlatFile, cfablur, 0, 2*BS); + else if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::vh_ff]) + //slightly more complicated blur if trying to correct both vertical and horizontal anomalies + cfaboxblur(riFlatFile, cfablur, BS, BS);//first do area blur to correct vignette + else //(raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::area_ff]) + cfaboxblur(riFlatFile, cfablur, BS, BS); + + float refctrval,reflocval,refcolor[2][2],vignettecorr,colorcastcorr; + //find center ave values by channel + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { + refcolor[m][n] = MAX(0,cfablur[(2*(H>>2)+m)*W+2*(W>>2)+n] - ri->get_black()); } - } - }else{ - for (int row = 0; row < H; row++) { - for (int col = 0; col < W; col++) { - rawData[row][3*col+0] = src->data[row][3*col+0]; - rawData[row][3*col+1] = src->data[row][3*col+1]; - rawData[row][3*col+2] = src->data[row][3*col+2]; + + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { + for (int row = 0; row+m < H; row+=2) + for (int col = 0; col+n < W; col+=2) { + + vignettecorr = ( refcolor[m][n]/MAX(1e-5,cfablur[(row+m)*W+col+n]-ri->get_black()) ); + rawData[row+m][col+n] = CLIP(round(rawData[row+m][col+n] * vignettecorr)); + //would rather not clip, but this is the restriction of ushort + } } + + if (raw.ff_BlurType == RAWParams::ff_BlurTypestring[RAWParams::vh_ff]) { + float (*cfablur1); + cfablur1 = (float (*)) calloc (H*W, sizeof *cfablur1); + float (*cfablur2); + cfablur2 = (float (*)) calloc (H*W, sizeof *cfablur2); + //slightly more complicated blur if trying to correct both vertical and horizontal anomalies + cfaboxblur(riFlatFile, cfablur1, 0, 2*BS);//now do horizontal blur + cfaboxblur(riFlatFile, cfablur2, 2*BS, 0);//now do vertical blur + + float vlinecorr, hlinecorr; + + for (int m=0; m<2; m++) + for (int n=0; n<2; n++) { + for (int row = 0; row+m < H; row+=2) + for (int col = 0; col+n < W; col+=2) { + hlinecorr = ( MAX(1e-5,cfablur[(row+m)*W+col+n]-ri->get_black())/MAX(1e-5,cfablur1[(row+m)*W+col+n]-ri->get_black()) ); + vlinecorr = ( MAX(1e-5,cfablur[(row+m)*W+col+n]-ri->get_black())/MAX(1e-5,cfablur2[(row+m)*W+col+n]-ri->get_black()) ); + rawData[row+m][col+n] = CLIP(round(rawData[row+m][col+n] * hlinecorr * vlinecorr)); + //would rather not clip, but this is the restriction of ushort + } + } + free (cfablur1); + free (cfablur2); } + + free (cfablur); + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +//#undef BS + + } } } + + void RawImageSource::cfaboxblur(RawImage *riFlatFile, float* cfablur, int boxH, int boxW ) { + + float (*temp); + temp = (float (*)) calloc (H*W, sizeof *temp); + + //box blur cfa image; box size = BS + //horizontal blur + for (int row = 0; row < H; row++) { + int len = boxW/2 + 1; + temp[row*W+0] = (float)riFlatFile->data[row][0]/len; + temp[row*W+1] = (float)riFlatFile->data[row][1]/len; + for (int j=2; j<=boxW; j+=2) { + temp[row*W+0] += (float)riFlatFile->data[row][j]/len; + temp[row*W+1] += (float)riFlatFile->data[row][j+1]/len; + } + for (int col=2; col<=boxW; col+=2) { + temp[row*W+col] = (temp[row*W+col-2]*len + riFlatFile->data[row][col+boxW])/(len+1); + temp[row*W+col+1] = (temp[row*W+col-1]*len + riFlatFile->data[row][col+boxW+1])/(len+1); + len ++; + } + for (int col = boxW+2; col < W-boxW; col++) { + temp[row*W+col] = temp[row*W+col-2] + ((float)(riFlatFile->data[row][col+boxW] - riFlatFile->data[row][col-boxW-2]))/len; + } + for (int col=W-boxW; coldata[row][col-boxW-2])/(len-1); + if ((W&1)==0) + temp[row*W+col+1] = (temp[row*W+col-1]*len - riFlatFile->data[row][col-boxW-1])/(len-1); + len --; + } + } + + //vertical blur + for (int col = 0; col < W; col++) { + int len = boxH/2 + 1; + cfablur[0*W+col] = temp[0*W+col]/len; + cfablur[1*W+col] = temp[1*W+col]/len; + for (int i=2; iisBayer()) { - double d = CLIP(initialGain*(ri->data[i][3*j]-cblack[0])*scale_mul[0]); + double d = CLIP(initialGain*(rawData[i][3*j])); if (d>64000) continue; avg_r += d; rn++; - d = CLIP(initialGain*(ri->data[i][3*j+1]-cblack[1])*scale_mul[1]); + d = CLIP(initialGain*(rawData[i][3*j+1])); if (d>64000) continue; avg_g += d; gn++; - d = CLIP(initialGain*(ri->data[i][3*j+2]-cblack[2])*scale_mul[2]); + d = CLIP(initialGain*(rawData[i][3*j+2])); if (d>64000) continue; avg_b += d; bn++; } else { int c = FC( i, j); - double d = CLIP(initialGain*(ri->data[i][j]-cblack[c])*scale_mul[c]); + double d = CLIP(initialGain*(rawData[i][j])); if (d>64000) continue; double dp = d; @@ -2158,9 +2314,9 @@ int RawImageSource::getAEHistogram (unsigned int* histogram, int& histcompr) { if (!ri->isBayer()) { for (int i=32; idata[i][3*j] -cblack[0])*scale_mul[0]); - double dg = CLIP(initialGain*(ri->data[i][3*j+1]-cblack[1])*scale_mul[1]); - double db = CLIP(initialGain*(ri->data[i][3*j+2]-cblack[2])*scale_mul[2]); + double dr = CLIP(initialGain*(rawData[i][3*j] )); + double dg = CLIP(initialGain*(rawData[i][3*j+1])); + double db = CLIP(initialGain*(rawData[i][3*j+2])); if (dr>64000 || dg>64000 || db>64000) continue; avg_r += dr; rn++; avg_g += dg; @@ -2179,10 +2335,10 @@ int RawImageSource::getAEHistogram (unsigned int* histogram, int& histcompr) { for (int i=32; idata[i][j] -cblack[FC(i,j)])*scale_mul[FC(i,j)]); - d[0][1] = CLIP(initialGain*(ri->data[i][j+1] -cblack[FC(i,j+1)])*scale_mul[FC(i,j+1)]); - d[1][0] = CLIP(initialGain*(ri->data[i+1][j] -cblack[FC(i+1,j)])*scale_mul[FC(i+1,j)]); - d[1][1] = CLIP(initialGain*(ri->data[i+1][j+1]-cblack[FC(i+1,j+1)])*scale_mul[FC(i+1,j+1)]); + d[0][0] = CLIP(initialGain*(rawData[i][j] )); + d[0][1] = CLIP(initialGain*(rawData[i][j+1] )); + d[1][0] = CLIP(initialGain*(rawData[i+1][j] )); + d[1][1] = CLIP(initialGain*(rawData[i+1][j+1])); if ( d[0][0]>64000 || d[0][1]>64000 || d[1][0]>64000 || d[1][1]>64000 ) continue; avg_r += d[ey][ex]; avg_g += d[1-ey][ex] + d[ey][1-ex]; @@ -2281,17 +2437,17 @@ ColorTemp RawImageSource::getSpotWB (std::vector red, std::vectordata[yr][3*xr] -cblack[0])*scale_mul[0]>52500 || - initialGain*(ri->data[yg][3*xg+1]-cblack[1])*scale_mul[1]>52500 || - initialGain*(ri->data[yb][3*xb+2]-cblack[2])*scale_mul[2]>52500) continue; + if (initialGain*(rawData[yr][3*xr] )>52500 || + initialGain*(rawData[yg][3*xg+1])>52500 || + initialGain*(rawData[yb][3*xb+2])>52500) continue; xmin = MIN(xr,MIN(xg,xb)); xmax = MAX(xr,MAX(xg,xb)); ymin = MIN(yr,MIN(yg,yb)); ymax = MAX(yr,MAX(yg,yb)); if (xmin>=0 && ymin>=0 && xmaxdata[yr][3*xr] -cblack[0])*scale_mul[0]; - greens += (ri->data[yg][3*xg+1]-cblack[1])*scale_mul[1]; - blues += (ri->data[yb][3*xb+2]-cblack[2])*scale_mul[2]; + reds += (rawData[yr][3*xr] ); + greens += (rawData[yg][3*xg+1]); + blues += (rawData[yb][3*xb+2]); rn++; } } @@ -2308,15 +2464,15 @@ ColorTemp RawImageSource::getSpotWB (std::vector red, std::vector=0 && yv>=0 && xvdata[yv][xv]-cblack[c])*scale_mul[c]; + rloc += (rawData[yv][xv]); rnbrs++; continue; }else if (c==2 && xv>=0 && yv>=0 && xvdata[yv][xv]-cblack[c])*scale_mul[c]; + bloc += (rawData[yv][xv]); bnbrs++; continue; } else { // GREEN - gloc += (ri->data[yv][xv]-cblack[c])*scale_mul[c]; + gloc += (rawData[yv][xv]); gnbrs++; continue; } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index d2a1f3fe4..2326fd47c 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -114,8 +114,9 @@ class RawImageSource : public ImageSource { int load (Glib::ustring fname, bool batch = false); void preprocess (const RAWParams &raw); void demosaic (const RAWParams &raw); - void copyOriginalPixels( RawImage *ri, RawImage *riDark ); - void scaleColors( int winx,int winy,int winw,int winh ); + void copyOriginalPixels(const RAWParams &raw, RawImage *ri, RawImage *riDark, RawImage *riFlatFile ); + void cfaboxblur (RawImage *riFlatFile, float* cfablur, int boxH, int boxW ); + void scaleColors (int winx,int winy,int winw,int winh ); void getImage (ColorTemp ctemp, int tran, Image16* image, PreviewProps pp, HRecParams hrp, ColorManagementParams cmp, RAWParams raw); ColorTemp getWB () { return wb; } ColorTemp getAutoWB (); diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 99fd0d16f..b786f3f7e 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -128,5 +128,11 @@ DEFRINGE, // EvDefringeEnabled, DEFRINGE, // EvDefringeRadius, DEFRINGE, // EvDefringeThreshold, RESIZE, // EvResizeBoundingBox -RESIZE // EvResizeAppliesTo +RESIZE, // EvResizeAppliesTo +FLATFIELD, // EvFlatFieldFile, +FLATFIELD, // EvFlatFieldAutoSelect, +FLATFIELD, // EvFlatFieldBlurRadius, +FLATFIELD // EvFlatFieldBlurType, + }; + diff --git a/rtengine/refreshmap.h b/rtengine/refreshmap.h index 489913c7b..ed848b35b 100644 --- a/rtengine/refreshmap.h +++ b/rtengine/refreshmap.h @@ -55,6 +55,7 @@ #define WHITEBALANCE (M_INIT|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define DEMOSAIC (M_RAW|M_INIT|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define DARKFRAME (M_PREPROC|M_RAW|M_INIT|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) +#define FLATFIELD (M_PREPROC|M_RAW|M_INIT|M_TRANSFORM|M_BLURMAP|M_AUTOEXP|M_RGBCURVE|M_LUMACURVE|M_LUMINANCE|M_COLOR) #define COLORBOOST M_COLOR #define COLORDENOISE M_COLOR #define DIRPYRDENOISE (M_COLOR|M_LUMINANCE) diff --git a/rtengine/settings.h b/rtengine/settings.h index e3836418e..0f022664b 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -29,7 +29,8 @@ namespace rtengine { int colorimetricIntent; ///< Colorimetric intent used at color space conversions Glib::ustring monitorProfile; ///< ICC profile of the monitor (full path recommended) bool verbose; - Glib::ustring darkFramesPath; ///< The default directory for dark frames + Glib::ustring darkFramesPath; ///< The default directory for dark frames + Glib::ustring flatFieldsPath; ///< The default directory for flat fields /** Creates a new instance of Settings. * @return a pointer to the new Settings instance. */ diff --git a/rtgui/filebrowser.cc b/rtgui/filebrowser.cc index 474890e72..a90cdd15b 100644 --- a/rtgui/filebrowser.cc +++ b/rtgui/filebrowser.cc @@ -24,6 +24,7 @@ #include #include #include +#include extern Options options; @@ -63,6 +64,10 @@ FileBrowser::FileBrowser () pmenu->attach (*(autoDF = new Gtk::MenuItem (M("FILEBROWSER_AUTODARKFRAME"))), 0, 1, p, p+1); p++; pmenu->attach (*(thisIsDF = new Gtk::MenuItem (M("FILEBROWSER_MOVETODARKFDIR"))), 0, 1, p, p+1); p++; pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; + pmenu->attach (*(selectFF = new Gtk::MenuItem (M("FILEBROWSER_SELECTFLATFIELD"))), 0, 1, p, p+1); p++; + pmenu->attach (*(autoFF = new Gtk::MenuItem (M("FILEBROWSER_AUTOFLATFIELD"))), 0, 1, p, p+1); p++; + pmenu->attach (*(thisIsFF = new Gtk::MenuItem (M("FILEBROWSER_MOVETOFLATFIELDDIR"))), 0, 1, p, p+1); p++; + pmenu->attach (*(new Gtk::SeparatorMenuItem ()), 0, 1, p, p+1); p++; pmenu->attach (*(copyprof = new Gtk::MenuItem (M("FILEBROWSER_COPYPROFILE"))), 0, 1, p, p+1); p++; pmenu->attach (*(pasteprof = new Gtk::MenuItem (M("FILEBROWSER_PASTEPROFILE"))), 0, 1, p, p+1); p++; pmenu->attach (*(partpasteprof = new Gtk::MenuItem (M("FILEBROWSER_PARTIALPASTEPROFILE"))), 0, 1, p, p+1); p++; @@ -94,6 +99,9 @@ FileBrowser::FileBrowser () selectDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selectDF)); autoDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), autoDF)); thisIsDF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated),thisIsDF )); + selectFF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), selectFF)); + autoFF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), autoFF)); + thisIsFF->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated),thisIsFF )); copyprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), copyprof)); pasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), pasteprof)); partpasteprof->signal_activate().connect (sigc::bind(sigc::mem_fun(*this, &FileBrowser::menuItemActivated), partpasteprof)); @@ -336,7 +344,49 @@ void FileBrowser::menuItemActivated (Gtk::MenuItem* m) { // Reinit cache rtengine::dfm.init( options.rtSettings.darkFramesPath ); } - }else if (m==copyprof) + } + else if (m==autoFF){ + for (int i=0; ithumbnail->getProcParams(); + pp.raw.ff_AutoSelect= true; + pp.raw.ff_file.clear(); + mselected[i]->thumbnail->setProcParams(pp,FILEBROWSER,false); + } + } + else if (m==selectFF){ + if( mselected.size() > 0 ){ + rtengine::procparams::ProcParams pp=mselected[0]->thumbnail->getProcParams(); + Gtk::FileChooserDialog fc("Flat Field",Gtk::FILE_CHOOSER_ACTION_OPEN ); + fc.add_button( Gtk::StockID("gtk-cancel"), Gtk::RESPONSE_CANCEL); + fc.add_button( Gtk::StockID("gtk-apply"), Gtk::RESPONSE_APPLY); + if( pp.raw.ff_file.empty()) + fc.set_current_folder( options.rtSettings.flatFieldsPath ); + else + fc.set_filename( pp.raw.ff_file ); + if( fc.run() == Gtk::RESPONSE_APPLY ){ + for (int i=0; ithumbnail->getProcParams(); + pp.raw.ff_file= fc.get_filename(); + pp.raw.ff_AutoSelect= false; + mselected[i]->thumbnail->setProcParams(pp,FILEBROWSER,false); + } + } + } + } + else if( m==thisIsFF){ + if( options.rtSettings.flatFieldsPath.size() >0 && Gio::File::create_for_path(options.rtSettings.flatFieldsPath)->query_exists() ){ + for (int i=0; i file = Gio::File::create_for_path ( mselected[i]->filename ); + if( !file )continue; + Glib::ustring destName = options.rtSettings.flatFieldsPath+ "/" + file->get_basename(); + Glib::RefPtr dest = Gio::File::create_for_path ( destName ); + file->move( dest ); + } + // Reinit cache + rtengine::ffm.init( options.rtSettings.flatFieldsPath ); + } + } + else if (m==copyprof) copyProfile (); else if (m==pasteprof) pasteProfile (); diff --git a/rtgui/filebrowser.h b/rtgui/filebrowser.h index ef8290ff9..dce75cca0 100644 --- a/rtgui/filebrowser.h +++ b/rtgui/filebrowser.h @@ -61,6 +61,9 @@ class FileBrowser : public ThumbBrowserBase, public LWButtonListener { Gtk::MenuItem* selectDF; Gtk::MenuItem* thisIsDF; Gtk::MenuItem* autoDF; + Gtk::MenuItem* selectFF; + Gtk::MenuItem* thisIsFF; + Gtk::MenuItem* autoFF; Gtk::MenuItem* copyprof; Gtk::MenuItem* pasteprof; Gtk::MenuItem* partpasteprof; diff --git a/rtgui/options.cc b/rtgui/options.cc index 6f2d390d7..de2521702 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -135,6 +135,7 @@ void Options::setDefaults () { rtSettings.dualThreadEnabled = true; rtSettings.darkFramesPath = ""; + rtSettings.flatFieldsPath = ""; #ifdef WIN32 rtSettings.iccDirectory = "C:/WINDOWS/System32/spool/drivers/color"; #else @@ -189,8 +190,9 @@ if (keyFile.has_group ("General")) { if (keyFile.has_key ("General", "Theme")) theme = keyFile.get_string ("General", "Theme"); if (keyFile.has_key ("General", "UseSystemTheme")) useSystemTheme = keyFile.get_boolean ("General", "UseSystemTheme"); if (keyFile.has_key ("General", "FirstRun")) firstRun = keyFile.get_boolean ("General", "FirstRun"); - if( keyFile.has_key ("General", "DarkFramesPath")) rtSettings.darkFramesPath = keyFile.get_string("General", "DarkFramesPath"); - if( keyFile.has_key ("General", "Verbose")) rtSettings.verbose = keyFile.get_boolean ( "General", "Verbose"); + if( keyFile.has_key ("General", "DarkFramesPath")) rtSettings.darkFramesPath = keyFile.get_string("General", "DarkFramesPath"); + if( keyFile.has_key ("General", "FlatFieldsPath")) rtSettings.flatFieldsPath = keyFile.get_string("General", "FlatFieldsPath"); + if( keyFile.has_key ("General", "Verbose")) rtSettings.verbose = keyFile.get_boolean ( "General", "Verbose"); } if (keyFile.has_group ("External Editor")) { @@ -336,8 +338,9 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_boolean ("General", "UseSystemTheme", useSystemTheme); keyFile.set_integer ("General", "Version", 290); keyFile.set_boolean ("General", "FirstRun", firstRun); - keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); - keyFile.set_boolean ("General", "Verbose", rtSettings.verbose); + keyFile.set_string ("General", "DarkFramesPath", rtSettings.darkFramesPath); + keyFile.set_string ("General", "FlatFieldsPath", rtSettings.flatFieldsPath); + keyFile.set_boolean ("General", "Verbose", rtSettings.verbose); keyFile.set_integer ("External Editor", "EditorKind", editorToSendTo); keyFile.set_string ("External Editor", "GimpDir", gimpDir); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 1899180da..b6bcd8026 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -140,7 +140,11 @@ void ParamsEdited::set (bool v) { raw.ccSteps = v; raw.dmethod = v; raw.dcbIterations = v; - raw.dcbEnhance = v; + raw.dcbEnhance = v; + raw.ff_file = v; + raw.ff_AutoSelect = v; + raw.ff_BlurRadius = v; + raw.ff_BlurType = v; equalizer.enabled = v; dirpyrequalizer.enabled = v; hsvequalizer.enabled = v; @@ -294,6 +298,10 @@ void ParamsEdited::initFrom (const std::vector raw.exPreser = raw.exPreser && p.raw.preser == other.raw.preser; //exposi raw.darkFrame = raw.darkFrame && p.raw.dark_frame == other.raw.dark_frame; raw.dfAuto = raw.dfAuto && p.raw.df_autoselect == other.raw.df_autoselect; + raw.ff_file = raw.ff_file && p.raw.ff_file == other.raw.ff_file; + raw.ff_AutoSelect = raw.ff_AutoSelect && p.raw.ff_AutoSelect == other.raw.ff_AutoSelect; + raw.ff_BlurRadius = raw.ff_BlurRadius && p.raw.ff_BlurRadius == other.raw.ff_BlurRadius; + raw.ff_BlurType = raw.ff_BlurType && p.raw.ff_BlurType == other.raw.ff_BlurType; raw.greenEq = raw.greenEq && p.raw.greenthresh == other.raw.greenthresh; raw.hotDeadPixel = raw.hotDeadPixel && p.raw.hotdeadpix_filt == other.raw.hotdeadpix_filt; raw.linenoise = raw.linenoise && p.raw.linenoise == other.raw.linenoise; @@ -446,6 +454,12 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (raw.linenoise) toEdit.raw.linenoise = mods.raw.linenoise; if (raw.darkFrame) toEdit.raw.dark_frame = mods.raw.dark_frame; if (raw.dfAuto) toEdit.raw.df_autoselect= mods.raw.df_autoselect; + + if (raw.ff_file) toEdit.raw.ff_file= mods.raw.ff_file; + if (raw.ff_AutoSelect) toEdit.raw.ff_AutoSelect= mods.raw.ff_AutoSelect; + if (raw.ff_BlurRadius) toEdit.raw.ff_BlurRadius= mods.raw.ff_BlurRadius; + if (raw.ff_BlurType) toEdit.raw.ff_BlurType= mods.raw.ff_BlurType; + 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]; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 4706b2891..73fea610d 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -288,6 +288,10 @@ class RAWParamsEdited { bool linenoise; bool darkFrame; bool dfAuto; + bool ff_file; + bool ff_AutoSelect; + bool ff_BlurRadius; + bool ff_BlurType; bool exCorrection; bool exPos; bool exPreser; diff --git a/rtgui/partialpastedlg.cc b/rtgui/partialpastedlg.cc index 88dd47e32..67fd1c6da 100644 --- a/rtgui/partialpastedlg.cc +++ b/rtgui/partialpastedlg.cc @@ -24,12 +24,15 @@ PartialPasteDlg::PartialPasteDlg () { set_modal (true); set_title (M("PARTIALPASTE_DIALOGLABEL")); + everything = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EVERYTHING"))); + basic = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_BASICGROUP"))); luminance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LUMINANCEGROUP"))); color = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COLORGROUP"))); lens = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LENSGROUP"))); composition = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_COMPOSITIONGROUP"))); metaicm = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_METAICMGROUP"))); + raw = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_RAWGROUP"))); // options in basic: wb = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_WHITEBALANCE"))); @@ -38,7 +41,7 @@ PartialPasteDlg::PartialPasteDlg () { // options in luminance: sharpen = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHARPENING"))); - impden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IMPULSEDENOISE"))); + impden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IMPULSEDENOISE"))); lumaden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LUMADENOISE"))); labcurve = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_LABCURVE"))); sh = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_SHADOWSHIGHLIGHTS"))); @@ -69,9 +72,18 @@ PartialPasteDlg::PartialPasteDlg () { iptc = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IPTCINFO"))); icm = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_ICMSETTINGS"))); - Gtk::VBox* vboxes[6]; - Gtk::HSeparator* hseps[6]; - for (int i=0; i<6; i++) { + // options in raw: + df_file = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DARKFRAMEFILE"))); + df_AutoSelect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DARKFRAMEAUTOSELECT"))); + ff_file = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDFILE"))); + ff_AutoSelect = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDAUTOSELECT"))); + ff_BlurRadius = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURRADIUS"))); + ff_BlurType = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_FLATFIELDBLURTYPE"))); + + Gtk::VBox* vboxes[7]; + Gtk::HSeparator* hseps[7]; + for (int i=0; i<7; i++) { + vboxes[i] = Gtk::manage (new Gtk::VBox ()); vboxes[i]->set_border_width (16); hseps[i] = Gtk::manage (new Gtk::HSeparator ()); @@ -86,7 +98,7 @@ PartialPasteDlg::PartialPasteDlg () { vboxes[1]->pack_start (*luminance, Gtk::PACK_SHRINK, 2); vboxes[1]->pack_start (*hseps[1], Gtk::PACK_SHRINK, 2); vboxes[1]->pack_start (*sharpen, Gtk::PACK_SHRINK, 2); - vboxes[1]->pack_start (*impden, Gtk::PACK_SHRINK, 2); + vboxes[1]->pack_start (*impden, Gtk::PACK_SHRINK, 2); vboxes[1]->pack_start (*lumaden, Gtk::PACK_SHRINK, 2); vboxes[1]->pack_start (*labcurve, Gtk::PACK_SHRINK, 2); vboxes[1]->pack_start (*sh, Gtk::PACK_SHRINK, 2); @@ -98,7 +110,7 @@ PartialPasteDlg::PartialPasteDlg () { vboxes[2]->pack_start (*colormixer, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*colorshift, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*colorboost, Gtk::PACK_SHRINK, 2); - vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2); + vboxes[2]->pack_start (*hsveq, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*colorden, Gtk::PACK_SHRINK, 2); vboxes[2]->pack_start (*dirpyrden, Gtk::PACK_SHRINK, 2); @@ -116,54 +128,80 @@ PartialPasteDlg::PartialPasteDlg () { vboxes[4]->pack_start (*crop, Gtk::PACK_SHRINK, 2); vboxes[4]->pack_start (*resize, Gtk::PACK_SHRINK, 2); - vboxes[5]->pack_start (*metaicm, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*raw, Gtk::PACK_SHRINK, 2); vboxes[5]->pack_start (*hseps[5], Gtk::PACK_SHRINK, 2); - vboxes[5]->pack_start (*exifch, Gtk::PACK_SHRINK, 2); - vboxes[5]->pack_start (*iptc, Gtk::PACK_SHRINK, 2); - vboxes[5]->pack_start (*icm, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*df_file, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*df_AutoSelect, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*ff_file, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*ff_AutoSelect, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*ff_BlurType, Gtk::PACK_SHRINK, 2); + vboxes[5]->pack_start (*ff_BlurRadius, Gtk::PACK_SHRINK, 2); - Gtk::VBox* vbleft = Gtk::manage (new Gtk::VBox ()); - Gtk::VBox* vbright = Gtk::manage (new Gtk::VBox ()); + vboxes[6]->pack_start (*metaicm, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*hseps[6], Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*exifch, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*iptc, Gtk::PACK_SHRINK, 2); + vboxes[6]->pack_start (*icm, Gtk::PACK_SHRINK, 2); - vbleft->set_border_width (16); - vbright->set_border_width (16); + Gtk::VBox* vbCol1 = Gtk::manage (new Gtk::VBox ()); + Gtk::VBox* vbCol2 = Gtk::manage (new Gtk::VBox ()); + Gtk::VBox* vbCol3 = Gtk::manage (new Gtk::VBox ()); + + vbCol1->set_border_width (16); + vbCol2->set_border_width (16); + vbCol3->set_border_width (16); for (int i=0; i<3; i++) - vbleft->pack_start (*vboxes[i]); + vbCol1->pack_start (*vboxes[i]); for (int i=3; i<6; i++) - vbright->pack_start (*vboxes[i]); + vbCol2->pack_start (*vboxes[i]); + for (int i=6; i<7; i++) + vbCol3->pack_start (*vboxes[i]); + Gtk::VBox* vbtop = Gtk::manage (new Gtk::VBox ()); + vbtop->pack_start (*everything, Gtk::PACK_SHRINK, 2); + vbtop->pack_start (*(Gtk::manage (new Gtk::HSeparator ()))); + vbtop->set_border_width (8); + + get_vbox()->pack_start (*vbtop); + Gtk::HBox* hbmain = Gtk::manage (new Gtk::HBox ()); - hbmain->pack_start (*vbleft); + hbmain->pack_start (*vbCol1); hbmain->pack_start (*(Gtk::manage (new Gtk::VSeparator ()))); - hbmain->pack_start (*vbright); + hbmain->pack_start (*vbCol2); + hbmain->pack_start (*(Gtk::manage (new Gtk::VSeparator ()))); + hbmain->pack_start (*vbCol3); get_vbox()->pack_start (*hbmain); + // This can be improved + // there is currently no binding of subsettings to CheckButton 'everything' for its inconsistent status + everythingConn = everything->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::everythingToggled)); basicConn = basic->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::basicToggled)); luminanceConn = luminance->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::luminanceToggled)); colorConn = color->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::colorToggled)); lensConn = lens->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::lensToggled)); compositionConn = composition->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::compositionToggled)); - metaicmConn = metaicm->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::metaicmToggled)); + metaicmConn = metaicm->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::metaicmToggled)); + rawConn = raw->signal_toggled().connect (sigc::mem_fun(*this, &PartialPasteDlg::rawToggled)); wbConn = wb->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); exposureConn = exposure->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); hlrecConn = hlrec->signal_toggled().connect (sigc::bind (sigc::mem_fun(*basic, &Gtk::CheckButton::set_inconsistent), true)); sharpenConn = sharpen->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); - impdenConn = impden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + impdenConn = impden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); lumadenConn = lumaden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); - labcurveConn = labcurve->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + labcurveConn = labcurve->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); shConn = sh->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); - dirpyreqConn = dirpyreq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); - waveqConn = waveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + dirpyreqConn = dirpyreq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); + waveqConn = waveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*luminance, &Gtk::CheckButton::set_inconsistent), true)); colormixerConn = colormixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); colorshiftConn = colorshift->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); colorboostConn = colorboost->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); - hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); - colordenConn = colorden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + hsveqConn = hsveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); + colordenConn = colorden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); dirpyrdenConn = dirpyrden->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true)); distortionConn = distortion->signal_toggled().connect (sigc::bind (sigc::mem_fun(*lens, &Gtk::CheckButton::set_inconsistent), true)); @@ -179,6 +217,13 @@ PartialPasteDlg::PartialPasteDlg () { iptcConn = iptc->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); icmConn = icm->signal_toggled().connect (sigc::bind (sigc::mem_fun(*metaicm, &Gtk::CheckButton::set_inconsistent), true)); + df_fileConn = df_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + df_AutoSelectConn = df_AutoSelect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_fileConn = ff_file->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_AutoSelectConn = ff_AutoSelect->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_BlurRadiusConn = ff_BlurRadius->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + ff_BlurTypeConn = ff_BlurType->signal_toggled().connect (sigc::bind (sigc::mem_fun(*raw, &Gtk::CheckButton::set_inconsistent), true)); + add_button (Gtk::StockID("gtk-ok"), 1); add_button (Gtk::StockID("gtk-cancel"), 0); set_response_sensitive (1); @@ -186,6 +231,71 @@ PartialPasteDlg::PartialPasteDlg () { show_all_children (); } +void PartialPasteDlg::everythingToggled () { + + basicConn.block (true); + luminanceConn.block (true); + colorConn.block (true); + lensConn.block (true); + compositionConn.block (true); + metaicmConn.block (true); + rawConn.block (true); + + everything->set_inconsistent (false); + + //toggle group headings + basic->set_active(everything->get_active()); + luminance->set_active(everything->get_active()); + color->set_active(everything->get_active()); + lens->set_active(everything->get_active()); + composition->set_active(everything->get_active()); + metaicm->set_active(everything->get_active()); + raw->set_active(everything->get_active()); + + //toggle group children + PartialPasteDlg::basicToggled (); + PartialPasteDlg::luminanceToggled (); + PartialPasteDlg::colorToggled (); + PartialPasteDlg::lensToggled (); + PartialPasteDlg::compositionToggled (); + PartialPasteDlg::metaicmToggled (); + PartialPasteDlg::rawToggled (); + + basicConn.block (false); + luminanceConn.block (false); + colorConn.block (false); + lensConn.block (false); + compositionConn.block (false); + metaicmConn.block (false); + rawConn.block (false); +} + +void PartialPasteDlg::rawToggled () { + + df_fileConn.block (true); + df_AutoSelectConn.block (true); + ff_fileConn.block (true); + ff_AutoSelectConn.block (true); + ff_BlurRadiusConn.block (true); + ff_BlurTypeConn.block (true); + + raw->set_inconsistent (false); + + df_file->set_active (raw->get_active ()); + df_AutoSelect->set_active (raw->get_active ()); + ff_file->set_active (raw->get_active ()); + ff_AutoSelect->set_active (raw->get_active ()); + ff_BlurRadius->set_active (raw->get_active ()); + ff_BlurType->set_active (raw->get_active ()); + + df_fileConn.block (false); + df_AutoSelectConn.block (false); + ff_fileConn.block (false); + ff_AutoSelectConn.block (false); + ff_BlurRadiusConn.block (false); + ff_BlurTypeConn.block (false); +} + void PartialPasteDlg::basicToggled () { wbConn.block (true); @@ -206,7 +316,7 @@ void PartialPasteDlg::basicToggled () { void PartialPasteDlg::luminanceToggled () { sharpenConn.block (true); - impdenConn.block (true); + impdenConn.block (true); lumadenConn.block (true); labcurveConn.block (true); shConn.block (true); @@ -216,7 +326,7 @@ void PartialPasteDlg::luminanceToggled () { luminance->set_inconsistent (false); sharpen->set_active (luminance->get_active ()); - impden->set_active (luminance->get_active ()); + impden->set_active (luminance->get_active ()); lumaden->set_active (luminance->get_active ()); labcurve->set_active (luminance->get_active ()); sh->set_active (luminance->get_active ()); @@ -237,6 +347,7 @@ void PartialPasteDlg::colorToggled () { colormixerConn.block (true); colorshiftConn.block (true); colorboostConn.block (true); + hsveqConn.block (true); colordenConn.block (true); dirpyrdenConn.block (true); @@ -245,15 +356,16 @@ void PartialPasteDlg::colorToggled () { colormixer->set_active (color->get_active ()); colorshift->set_active (color->get_active ()); colorboost->set_active (color->get_active ()); - hsveq->set_active (color->get_active ()); + hsveq->set_active (color->get_active ()); colorden->set_active (color->get_active ()); dirpyrden->set_active (color->get_active ()); colormixerConn.block (false); colorshiftConn.block (false); colorboostConn.block (false); + hsveqConn.block (false); colordenConn.block (false); - dirpyrdenConn.block (false); + dirpyrdenConn.block (false); } void PartialPasteDlg::lensToggled () { @@ -328,7 +440,7 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const r if (colormixer->get_active ()) dst->chmixer = src->chmixer; if (colorshift->get_active ()) dst->colorShift = src->colorShift; if (colorboost->get_active ()) dst->colorBoost = src->colorBoost; - if (hsveq->get_active ()) dst->hsvequalizer = src->hsvequalizer; + if (hsveq->get_active ()) dst->hsvequalizer = src->hsvequalizer; if (colorden->get_active ()) dst->colorDenoise = src->colorDenoise; if (dirpyrden->get_active ()) dst->dirpyrDenoise = src->dirpyrDenoise; @@ -343,6 +455,13 @@ void PartialPasteDlg::applyPaste (rtengine::procparams::ProcParams* dst, const r if (exifch->get_active ()) dst->exif = src->exif; if (iptc->get_active ()) dst->iptc = src->iptc; - if (icm->get_active ()) dst->icm = src->icm; + if (icm->get_active ()) dst->icm = src->icm; + + if (df_file->get_active ()) dst->raw.dark_frame = src->raw.dark_frame; + if (df_AutoSelect->get_active ()) dst->raw.df_autoselect = src->raw.df_autoselect; + if (ff_file->get_active ()) dst->raw.ff_file = src->raw.ff_file; + if (ff_AutoSelect->get_active ()) dst->raw.ff_AutoSelect = src->raw.ff_AutoSelect; + if (ff_BlurRadius->get_active ()) dst->raw.ff_BlurRadius = src->raw.ff_BlurRadius; + if (ff_BlurType->get_active ()) dst->raw.ff_BlurType = src->raw.ff_BlurType; } diff --git a/rtgui/partialpastedlg.h b/rtgui/partialpastedlg.h index 127b83833..2aa2e3914 100644 --- a/rtgui/partialpastedlg.h +++ b/rtgui/partialpastedlg.h @@ -25,6 +25,8 @@ class PartialPasteDlg : public Gtk::Dialog { public: + Gtk::CheckButton* everything; + // main groups: Gtk::CheckButton* basic; Gtk::CheckButton* luminance; @@ -32,6 +34,7 @@ class PartialPasteDlg : public Gtk::Dialog { Gtk::CheckButton* lens; Gtk::CheckButton* composition; Gtk::CheckButton* metaicm; + Gtk::CheckButton* raw; // options in basic: Gtk::CheckButton* wb; @@ -40,20 +43,20 @@ class PartialPasteDlg : public Gtk::Dialog { // options in luminance: Gtk::CheckButton* sharpen; - Gtk::CheckButton* impden; + Gtk::CheckButton* impden; Gtk::CheckButton* lumaden; Gtk::CheckButton* labcurve; Gtk::CheckButton* sh; - Gtk::CheckButton* dirpyreq; - Gtk::CheckButton* waveq; + Gtk::CheckButton* dirpyreq; + Gtk::CheckButton* waveq; // options in color: Gtk::CheckButton* colormixer; Gtk::CheckButton* colorshift; Gtk::CheckButton* colorboost; - Gtk::CheckButton* hsveq; + Gtk::CheckButton* hsveq; Gtk::CheckButton* colorden; - Gtk::CheckButton* dirpyrden; + Gtk::CheckButton* dirpyrden; // options in lens: @@ -72,13 +75,23 @@ class PartialPasteDlg : public Gtk::Dialog { Gtk::CheckButton* iptc; Gtk::CheckButton* icm; - sigc::connection basicConn, luminanceConn, colorConn, lensConn, compositionConn, metaicmConn; + // options in raw: + Gtk::CheckButton* df_file; + Gtk::CheckButton* df_AutoSelect; + Gtk::CheckButton* ff_file; + Gtk::CheckButton* ff_AutoSelect; + Gtk::CheckButton* ff_BlurRadius; + Gtk::CheckButton* ff_BlurType; + + sigc::connection everythingConn, basicConn, luminanceConn, colorConn, lensConn, compositionConn, metaicmConn, rawConn; + sigc::connection wbConn, exposureConn, hlrecConn; sigc::connection sharpenConn, impdenConn, lumadenConn, labcurveConn, shConn, dirpyreqConn, waveqConn, hsveqConn; sigc::connection colormixerConn, colorshiftConn, colorboostConn, colordenConn, dirpyrdenConn; sigc::connection distortionConn, cacorrConn, vignettingConn; sigc::connection coarserotConn, finerotConn, cropConn, resizeConn; sigc::connection exifchConn, iptcConn, icmConn; + sigc::connection df_fileConn, df_AutoSelectConn,ff_fileConn, ff_AutoSelectConn, ff_BlurRadiusConn, ff_BlurTypeConn; public: @@ -86,12 +99,14 @@ class PartialPasteDlg : public Gtk::Dialog { void applyPaste (rtengine::procparams::ProcParams* dst, const rtengine::procparams::ProcParams* src); + void everythingToggled (); void basicToggled (); void luminanceToggled (); void colorToggled (); void lensToggled (); void compositionToggled (); void metaicmToggled (); + void rawToggled (); }; #endif diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc index b584cfee5..d2a8dcf41 100644 --- a/rtgui/preferences.cc +++ b/rtgui/preferences.cc @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -278,6 +279,27 @@ Gtk::Widget* Preferences::getProcParamsPanel () { mvbpp->pack_start ( *fdf , Gtk::PACK_SHRINK, 4); mvbpp->set_border_width (4); + //dfconn = darkFrameDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::darkFrameChanged), true); + dfconn = darkFrameDir->signal_current_folder_changed().connect ( sigc::mem_fun(*this, &Preferences::darkFrameChanged), true); + + // FLATFIELD + Gtk::Frame* fff = Gtk::manage (new Gtk::Frame (M("PREFERENCES_FLATFIELD")) ); + Gtk::HBox* hb43 = Gtk::manage (new Gtk::HBox ()); + flatFieldDir = Gtk::manage(new Gtk::FileChooserButton(M("PREFERENCES_FLATFIELDSDIR"), Gtk::FILE_CHOOSER_ACTION_SELECT_FOLDER)); + Gtk::Label *ffLab = Gtk::manage(new Gtk::Label(M("PREFERENCES_FLATFIELDSDIR"))); + hb43->pack_start(*ffLab , Gtk::PACK_SHRINK, 4 ); + hb43->pack_start(*flatFieldDir); + ffLabel = Gtk::manage(new Gtk::Label("Found:")); + Gtk::VBox* vbff = Gtk::manage (new Gtk::VBox ()); + vbff->pack_start( *hb43, Gtk::PACK_SHRINK, 4); + vbff->pack_start( *ffLabel, Gtk::PACK_SHRINK, 4 ); + fff->add( *vbff ); + mvbpp->pack_start ( *fff , Gtk::PACK_SHRINK, 4); + mvbpp->set_border_width (4); + + //ffconn = flatFieldDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::flatFieldChanged), true); + ffconn = flatFieldDir->signal_current_folder_changed().connect ( sigc::mem_fun(*this, &Preferences::flatFieldChanged), true); + std::vector pnames; if (options.multiUser) parseDir (Options::rtdir + "/" + options.profilePath, pnames, paramFileExtension); @@ -287,8 +309,6 @@ Gtk::Widget* Preferences::getProcParamsPanel () { iprofiles->append_text (pnames[i]); } - dfconn = darkFrameDir->signal_file_set().connect ( sigc::mem_fun(*this, &Preferences::darkFrameChanged), true); - Gtk::Frame* fmd = Gtk::manage (new Gtk::Frame (M("PREFERENCES_METADATA"))); Gtk::VBox* vbmd = Gtk::manage (new Gtk::VBox ()); ckbTunnelMetaData = Gtk::manage (new Gtk::CheckButton (M("PREFERENCES_TUNNELMETADATA"))); @@ -829,6 +849,7 @@ void Preferences::storePreferences () { moptions.tunnelMetaData = ckbTunnelMetaData->get_active (); moptions.rtSettings.darkFramesPath = darkFrameDir->get_filename(); + moptions.rtSettings.flatFieldsPath = flatFieldDir->get_filename(); int i = 0; moptions.baBehav.resize (ADDSET_PARAM_NUM); @@ -853,6 +874,7 @@ void Preferences::fillPreferences () { tconn.block (true); dfconn.block (true); + ffconn.block (true); rprofiles->set_active_text (moptions.defProfRaw); iprofiles->set_active_text (moptions.defProfImg); @@ -936,8 +958,15 @@ void Preferences::fillPreferences () { else editorLayout->set_active(moptions.multiDisplayMode ? 3 : 2); - darkFrameDir->set_filename( moptions.rtSettings.darkFramesPath ); - updateDFinfos(); + //darkFrameDir->set_filename( moptions.rtSettings.darkFramesPath ); + //updateDFinfos(); + darkFrameDir->set_current_folder( moptions.rtSettings.darkFramesPath ); + darkFrameChanged (); + + //flatFieldDir->set_filename( moptions.rtSettings.flatFieldsPath ); + //updateFFinfos(); + flatFieldDir->set_current_folder( moptions.rtSettings.flatFieldsPath ); + flatFieldChanged (); addc.block (true); setc.block (true); @@ -955,6 +984,7 @@ void Preferences::fillPreferences () { setc.block (false); tconn.block (false); dfconn.block (false); + ffconn.block (false); chOverwriteOutputFile->set_active (moptions.overwriteOutputFile); @@ -1112,17 +1142,38 @@ void Preferences::clearAllPressed () { void Preferences::darkFrameChanged () { - Glib::ustring s(darkFrameDir->get_filename()); - if( s.compare( rtengine::dfm.getPathname()) !=0 ){ + //Glib::ustring s(darkFrameDir->get_filename()); + Glib::ustring s(darkFrameDir->get_current_folder()); + //if( s.compare( rtengine::dfm.getPathname()) !=0 ){ rtengine::dfm.init( s ); updateDFinfos(); - } + //} } + +void Preferences::flatFieldChanged () +{ + //Glib::ustring s(flatFieldDir->get_filename()); + Glib::ustring s(flatFieldDir->get_current_folder()); + //if( s.compare( rtengine::ffm.getPathname()) !=0 ){ + rtengine::ffm.init( s ); + updateFFinfos(); + //} +} + void Preferences::updateDFinfos() { int t1,t2; rtengine::dfm.getStat(t1,t2); std::ostringstream s; - s << "Found: "<< t1 << " shots, " << t2 << " templates"; + s << M("PREFERENCES_DARKFRAMEFOUND")<<": "<< t1 << " "<set_text(s.str()); } + +void Preferences::updateFFinfos() +{ + int t1,t2; + rtengine::ffm.getStat(t1,t2); + std::ostringstream s; + s << M("PREFERENCES_FLATFIELDFOUND")<<": "<< t1 << " "<set_text(s.str()); +} \ No newline at end of file diff --git a/rtgui/preferences.h b/rtgui/preferences.h index 2c6eead28..8c19e4b82 100644 --- a/rtgui/preferences.h +++ b/rtgui/preferences.h @@ -67,7 +67,9 @@ class Preferences : public Gtk::Dialog { Gtk::RadioButton* edPS; Gtk::RadioButton* edOther; Gtk::FileChooserButton* darkFrameDir; + Gtk::FileChooserButton* flatFieldDir; Gtk::Label *dfLabel; + Gtk::Label *ffLabel; Gtk::CheckButton* showDateTime; Gtk::CheckButton* showBasicExif; @@ -114,7 +116,7 @@ class Preferences : public Gtk::Dialog { Gtk::CheckButton* ckbTunnelMetaData; Options moptions; - sigc::connection tconn, fconn, usethcon, addc, setc, dfconn; + sigc::connection tconn, fconn, usethcon, addc, setc, dfconn, ffconn; Glib::ustring initialTheme; Glib::ustring initialFont; @@ -122,6 +124,7 @@ class Preferences : public Gtk::Dialog { void storePreferences (); void parseDir (Glib::ustring dirname, std::vector& items, Glib::ustring ext); void updateDFinfos (); + void updateFFinfos (); void workflowUpdate(); void themeChanged (); void useThemeChanged(); @@ -151,6 +154,7 @@ class Preferences : public Gtk::Dialog { void addExtPressed (); void delExtPressed (); void darkFrameChanged (); + void flatFieldChanged (); void clearProfilesPressed (); void clearThumbImagesPressed (); void clearAllPressed (); diff --git a/rtgui/preprocess.cc b/rtgui/preprocess.cc index 8d8f73edf..d34310e03 100644 --- a/rtgui/preprocess.cc +++ b/rtgui/preprocess.cc @@ -20,6 +20,7 @@ #include #include #include +#include using namespace rtengine; using namespace rtengine::procparams; @@ -35,7 +36,31 @@ PreProcess::PreProcess () hbdf->pack_start(*darkFrameFile); hbdf->pack_start(*btnReset, Gtk::PACK_SHRINK, 4); dfAuto = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_DFAUTOSELECT")))); + dfInfo = Gtk::manage(new Gtk::Label(".")); + dfInfo->set_alignment(0,0); //left align + hbff = Gtk::manage(new Gtk::HBox()); + flatFieldFile = Gtk::manage(new Gtk::FileChooserButton(M("TP_PREPROCESS_FLATFIELDFILE"), Gtk::FILE_CHOOSER_ACTION_OPEN)); + ffLabel = Gtk::manage(new Gtk::Label(M("TP_PREPROCESS_FLATFIELDFILE"))); + flatFieldFileReset = Gtk::manage(new Gtk::Button()); + flatFieldFileReset->set_image (*Gtk::manage(new Gtk::Image (Gtk::StockID("gtk-cancel"), Gtk::ICON_SIZE_BUTTON))); + hbff->pack_start(*ffLabel, Gtk::PACK_SHRINK, 4); + hbff->pack_start(*flatFieldFile); + hbff->pack_start(*flatFieldFileReset, Gtk::PACK_SHRINK, 4); + flatFieldAutoSelect = Gtk::manage(new Gtk::CheckButton((M("TP_PREPROCESS_FLATFIELDAUTOSELECT")))); + ffInfo = Gtk::manage(new Gtk::Label(".")); + ffInfo->set_alignment(0,0); //left align + flatFieldBlurRadius = Gtk::manage(new Adjuster (M("PREFERENCES_FLATFIELDBLURRADIUS"),0,200,2,32)); + flatFieldBlurRadius->setAdjusterListener (this); + flatFieldBlurRadius->show(); + + Gtk::HBox* hbffbt = Gtk::manage (new Gtk::HBox ()); + hbffbt->pack_start (*Gtk::manage (new Gtk::Label ( M("PREFERENCES_FLATFIELDBLURTYPE") +": "))); + flatFieldBlurType = Gtk::manage (new Gtk::ComboBoxText ()); + for( size_t i=0; i< procparams::RAWParams::numFlatFileBlurTypes;i++) + flatFieldBlurType->append_text(procparams::RAWParams::ff_BlurTypestring[i]); + flatFieldBlurType->set_active(0); + caAutocorrect = Gtk::manage(new Gtk::CheckButton((M("PREFERENCES_CACORRECTION")))); caRed = Gtk::manage(new Adjuster (M("PREFERENCES_CARED"),-4.0,4.0,0.1,0)); caRed->setAdjusterListener (this); @@ -70,11 +95,21 @@ PreProcess::PreProcess () pack_start( *hbdf, Gtk::PACK_SHRINK, 4); pack_start( *dfAuto, Gtk::PACK_SHRINK, 4); - pack_start( *Gtk::manage (new Gtk::HSeparator())); + pack_start( *dfInfo, Gtk::PACK_SHRINK, 4); + pack_start( *Gtk::manage (new Gtk::HSeparator())); + + pack_start( *hbff, Gtk::PACK_SHRINK, 4); + pack_start( *flatFieldAutoSelect, Gtk::PACK_SHRINK, 4); + pack_start( *ffInfo, Gtk::PACK_SHRINK, 4); + hbffbt->pack_end (*flatFieldBlurType); + pack_start( *hbffbt, Gtk::PACK_SHRINK, 4); + pack_start( *flatFieldBlurRadius, Gtk::PACK_SHRINK, 4); + pack_start( *Gtk::manage (new Gtk::HSeparator())); + pack_start( *hotDeadPixel, Gtk::PACK_SHRINK, 4); pack_start( *Gtk::manage (new Gtk::HSeparator())); pack_start( *caAutocorrect, Gtk::PACK_SHRINK, 4); - pack_start( *caRed, Gtk::PACK_SHRINK, 4); + pack_start( *caRed, Gtk::PACK_SHRINK, 4); pack_start( *caBlue, Gtk::PACK_SHRINK, 4); pack_start( *PexPos, Gtk::PACK_SHRINK, 4);//exposi pack_start( *PexPreser, Gtk::PACK_SHRINK, 4); @@ -89,6 +124,10 @@ PreProcess::PreProcess () hdpixelconn = hotDeadPixel->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::hotDeadPixelChanged), true); dfFile = darkFrameFile->signal_file_set().connect ( sigc::mem_fun(*this, &PreProcess::darkFrameChanged), true); btnReset->signal_clicked().connect( sigc::mem_fun(*this, &PreProcess::darkFrameReset), true ); + flatFieldFileconn = flatFieldFile->signal_file_set().connect ( sigc::mem_fun(*this, &PreProcess::flatFieldFileChanged), true); + flatFieldFileReset->signal_clicked().connect( sigc::mem_fun(*this, &PreProcess::flatFieldFile_Reset), true ); + flatFieldAutoSelectconn = flatFieldAutoSelect->signal_toggled().connect ( sigc::mem_fun(*this, &PreProcess::flatFieldAutoSelectChanged), true); + flatFieldBlurTypeconn = flatFieldBlurType->signal_changed().connect( sigc::mem_fun(*this, &PreProcess::flatFieldBlurTypeChanged) ); } @@ -98,6 +137,9 @@ void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEd caacsconn.block (true); dfautoconn.block(true); hdpixelconn.block (true); + flatFieldAutoSelectconn.block (true); + flatFieldBlurTypeconn.block (true); + if(pedited ){ dfAuto->set_inconsistent(!pedited->raw.dfAuto ); @@ -111,16 +153,63 @@ void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEd hotDeadPixel->set_inconsistent (!pedited->raw.hotDeadPixel); lineDenoise->setEditedState( pedited->raw.linenoise ? Edited : UnEdited ); greenEqThreshold->setEditedState( pedited->raw.greenEq ? Edited : UnEdited ); + flatFieldAutoSelect->set_inconsistent (!pedited->raw.ff_AutoSelect); + flatFieldBlurRadius->setEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited ); + if( !pedited->raw.ff_BlurType ) + flatFieldBlurType->set_active(procparams::RAWParams::numFlatFileBlurTypes); // No name } if (safe_file_test (pp->raw.dark_frame, Glib::FILE_TEST_EXISTS)) darkFrameFile->set_filename (pp->raw.dark_frame); else if( !options.rtSettings.darkFramesPath.empty() ) darkFrameFile->set_current_folder( options.rtSettings.darkFramesPath ); + hbdf->set_sensitive( !pp->raw.df_autoselect ); + + if (safe_file_test (pp->raw.ff_file, Glib::FILE_TEST_EXISTS)) + flatFieldFile->set_filename (pp->raw.ff_file); + else if( !options.rtSettings.flatFieldsPath.empty() ) + flatFieldFile->set_current_folder( options.rtSettings.flatFieldsPath ); + hbff->set_sensitive( !pp->raw.ff_AutoSelect ); + lastCA = pp->raw.ca_autocorrect; lastHot = pp->raw.hotdeadpix_filt; lastDFauto = pp->raw.df_autoselect; + + if( pp->raw.df_autoselect && dfp){ + // retrieve the auto-selected df filename + rtengine::RawImage *img = dfp->getDF(); + if( img ){ + std::ostringstream s; + s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; + dfInfo->set_text( s.str() ); + } + } + else dfInfo->set_text(""); + + lastFFAutoSelect = pp->raw.ff_AutoSelect; + if( pp->raw.ff_AutoSelect && ffp){ + // retrieve the auto-selected ff filename + rtengine::RawImage *img = ffp->getFF(); + if( img ){ + std::ostringstream s; + s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; + ffInfo->set_text( s.str() ); + } + } + else ffInfo->set_text(""); + + flatFieldAutoSelect ->set_active(pp->raw.ff_AutoSelect); + flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius); + flatFieldBlurType->set_active(procparams::RAWParams::numFlatFileBlurTypes); + + //flatFieldBlurType + for( size_t i=0; i< procparams::RAWParams::numFlatFileBlurTypes;i++) + if( pp->raw.ff_BlurType == procparams::RAWParams::ff_BlurTypestring[i]){ + flatFieldBlurType->set_active(i); + break; + } + dfAuto->set_active( pp->raw.df_autoselect ); caAutocorrect->set_active(pp->raw.ca_autocorrect); @@ -133,12 +222,19 @@ void PreProcess::read(const rtengine::procparams::ProcParams* pp, const ParamsEd lineDenoise->setValue (pp->raw.linenoise); greenEqThreshold->setValue (pp->raw.greenthresh); + flatFieldAutoSelect->set_active (pp->raw.ff_AutoSelect); + flatFieldBlurRadius->setValue (pp->raw.ff_BlurRadius); + dfChanged = false; + ffChanged = false; caacsconn.block (false); dfautoconn.block(false); hdpixelconn.block (false); + flatFieldAutoSelectconn.block (false); + flatFieldBlurTypeconn.block (false); + enableListener (); } @@ -147,6 +243,14 @@ void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedi { pp->raw.dark_frame = darkFrameFile->get_filename(); pp->raw.df_autoselect = dfAuto->get_active(); + pp->raw.ff_file = flatFieldFile->get_filename(); + pp->raw.ff_AutoSelect = flatFieldAutoSelect->get_active(); + pp->raw.ff_BlurRadius = (int)flatFieldBlurRadius->getValue(); + + int currentRow = flatFieldBlurType->get_active_row_number(); + if( currentRow>=0 && currentRow < procparams::RAWParams::numFlatFileBlurTypes) + pp->raw.ff_BlurType = procparams::RAWParams::ff_BlurTypestring[currentRow]; + pp->raw.ca_autocorrect = caAutocorrect->get_active(); pp->raw.cared = (double)caRed->getValue(); pp->raw.cablue = (double)caBlue->getValue(); @@ -160,6 +264,10 @@ void PreProcess::write( rtengine::procparams::ProcParams* pp, ParamsEdited* pedi if (pedited) { pedited->raw.darkFrame = dfChanged; pedited->raw.dfAuto = !dfAuto->get_inconsistent(); + pedited->raw.ff_file = ffChanged; + pedited->raw.ff_AutoSelect = !flatFieldAutoSelect->get_inconsistent(); + pedited->raw.ff_BlurRadius = flatFieldBlurRadius->getEditedState (); + pedited->raw.ff_BlurType = flatFieldBlurType->get_active_row_number() != procparams::RAWParams::numFlatFileBlurTypes; pedited->raw.linenoise = lineDenoise->getEditedState (); pedited->raw.greenEq= greenEqThreshold->getEditedState (); pedited->raw.caCorrection = !caAutocorrect->get_inconsistent(); @@ -188,6 +296,9 @@ void PreProcess::setBatchMode(bool batchMode) lineDenoise->showEditedCB (); greenEqThreshold->showEditedCB (); + + flatFieldBlurRadius->showEditedCB (); + } void PreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited) @@ -199,6 +310,8 @@ void PreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, PexPreser->setDefault( defParams->raw.preser); greenEqThreshold->setDefault (defParams->raw.greenthresh); + flatFieldBlurRadius->setDefault( defParams->raw.ff_BlurRadius); + if (pedited) { lineDenoise->setDefaultEditedState( pedited->raw.linenoise ? Edited : UnEdited); caRed->setDefaultEditedState( pedited->raw.caRed ? Edited : UnEdited); @@ -207,6 +320,7 @@ void PreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, PexPreser->setDefaultEditedState( pedited->raw.exPreser ? Edited : UnEdited); greenEqThreshold->setDefaultEditedState(pedited->raw.greenEq ? Edited : UnEdited); + flatFieldBlurRadius->setDefaultEditedState( pedited->raw.ff_BlurRadius ? Edited : UnEdited); }else{ lineDenoise->setDefaultEditedState( Irrelevant ); caRed->setDefaultEditedState( Irrelevant ); @@ -215,6 +329,7 @@ void PreProcess::setDefaults(const rtengine::procparams::ProcParams* defParams, PexPreser->setDefaultEditedState( Irrelevant ); greenEqThreshold->setDefaultEditedState(Irrelevant ); + flatFieldBlurRadius->setDefaultEditedState( Irrelevant ); } } @@ -250,6 +365,18 @@ void PreProcess::dfAutoChanged() lastDFauto = dfAuto->get_active (); } + + if(dfAuto->get_active() && dfp){ + // retrieve the auto-selected df filename + rtengine::RawImage *img = dfp->getDF(); + if( img ){ + std::ostringstream s; + s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; + dfInfo->set_text( s.str() ); + } + } + else{dfInfo->set_text("");} + hbdf->set_sensitive( !dfAuto->get_active() ); if (listener) listener->panelChanged (EvPreProcess, Glib::ustring(M("TP_PREPROCESS_DFAUTOSELECT"))+"="+(dfAuto->get_active()?"ON":"OFF") ); @@ -282,9 +409,87 @@ void PreProcess::darkFrameChanged() void PreProcess::darkFrameReset() { dfChanged=true; - darkFrameFile->set_current_name(""); + //darkFrameFile->set_current_name(""); darkFrameFile->set_filename (""); + + if( !options.rtSettings.darkFramesPath.empty() ) + darkFrameFile->set_current_folder( options.rtSettings.darkFramesPath ); + + dfInfo->set_text(""); if (listener) listener->panelChanged (EvPreProcess, Glib::ustring(M("TP_PREPROCESS_DARKFRAME"))+"=0" ); } + +void PreProcess::flatFieldFileChanged() +{ + ffChanged=true; + if (listener) + listener->panelChanged (EvFlatFieldFile, Glib::ustring(M("TP_PREPROCESS_FLATFIELDFILE"))+"="+flatFieldFile->get_filename()); +} + +void PreProcess::flatFieldFile_Reset() +{ + ffChanged=true; + //flatFieldFile->set_current_name(""); + flatFieldFile->set_filename (""); + + if( !options.rtSettings.flatFieldsPath.empty() ) + flatFieldFile->set_current_folder( options.rtSettings.flatFieldsPath ); + + ffInfo->set_text(""); + if (listener) + //listener->panelChanged (EvFlatFieldFile, Glib::ustring(M("TP_PREPROCESS_FLATFIELDFILE"))+"=None" ); + listener->panelChanged (EvFlatFieldFile, "None" ); +} + +void PreProcess::flatFieldBlurTypeChanged () +{ + int curSelection = flatFieldBlurType->get_active_row_number(); + + Glib::ustring s=""; + if( curSelection>=0 && curSelection < procparams::RAWParams::numFlatFileBlurTypes) + s = procparams::RAWParams::ff_BlurTypestring[curSelection]; + + if (listener) + //listener->panelChanged (EvFlatFieldBlurType, Glib::ustring(M("TP_PREPROCESS_FLATFIELDBLURTYPE"))+ "="+ s); + listener->panelChanged (EvFlatFieldBlurType, s); +} + +void PreProcess::flatFieldAutoSelectChanged() +{ + if (batchMode) { + if (flatFieldAutoSelect->get_inconsistent()) { + flatFieldAutoSelect->set_inconsistent (false); + flatFieldAutoSelectconn.block (true); + flatFieldAutoSelect->set_active (false); + flatFieldAutoSelectconn.block (false); + } + else if (lastFFAutoSelect) + flatFieldAutoSelect->set_inconsistent (true); + + lastFFAutoSelect = flatFieldAutoSelect->get_active (); + } + hbff->set_sensitive( !flatFieldAutoSelect->get_active() ); + + if( flatFieldAutoSelect->get_active() && ffp){ + // retrieve the auto-selected ff filename + rtengine::RawImage *img = ffp->getFF(); + if( img ){ + std::ostringstream s; + s << Glib::path_get_basename(img->get_filename()) << ":" <get_ISOspeed() << "ISO " << img->get_shutter() << "s"; + ffInfo->set_text( s.str() ); + } + } + else{ffInfo->set_text("");} + + if (listener) + //listener->panelChanged (EvFlatFieldAutoSelect, Glib::ustring(M("TP_PREPROCESS_FLATFIELDAUTOSELECT"))+"="+(flatFieldAutoSelect->get_active()?"ON":"OFF") ); + listener->panelChanged (EvFlatFieldAutoSelect, (flatFieldAutoSelect->get_active()?"ON":"OFF") ); + +} + +void PreProcess::flatFieldBlurRadiusChanged() +{ +//EvFlatFieldBlurRadius +} diff --git a/rtgui/preprocess.h b/rtgui/preprocess.h index c411cb07e..950941125 100644 --- a/rtgui/preprocess.h +++ b/rtgui/preprocess.h @@ -22,7 +22,19 @@ #include #include #include +#include +class DFProvider { + public: + virtual rtengine::RawImage* getDF() {} + // add other info here +}; + +class FFProvider { + public: + virtual rtengine::RawImage* getFF() {} + // add other info here +}; class PreProcess : public Gtk::VBox, public AdjusterListener, public ToolPanel{ @@ -33,7 +45,18 @@ class PreProcess : public Gtk::VBox, public AdjusterListener, public ToolPanel{ Gtk::HBox *hbdf; Gtk::Button *btnReset; Gtk::Label *dfLabel; + Gtk::Label *dfInfo; bool dfChanged; + + Gtk::FileChooserButton *flatFieldFile; + Gtk::Label *ffLabel; + Gtk::Label *ffInfo; + Gtk::Button *flatFieldFileReset; + Gtk::CheckButton* flatFieldAutoSelect; + Adjuster* flatFieldBlurRadius; + Gtk::ComboBoxText* flatFieldBlurType; + Gtk::HBox *hbff; + bool ffChanged; Adjuster* caRed; Adjuster* caBlue; @@ -45,9 +68,13 @@ class PreProcess : public Gtk::VBox, public AdjusterListener, public ToolPanel{ Gtk::CheckButton* caAutocorrect; Gtk::CheckButton* hotDeadPixel; Gtk::CheckButton* dfAuto; - bool lastCA,lastHot,lastDFauto; + bool lastCA,lastHot,lastDFauto, lastFFAutoSelect; + + DFProvider *dfp; + FFProvider *ffp; + + sigc::connection caacsconn,dfautoconn,hdpixelconn,dfFile,flatFieldFileconn,flatFieldAutoSelectconn,flatFieldBlurTypeconn; - sigc::connection caacsconn,dfautoconn,hdpixelconn,dfFile; public: PreProcess (); @@ -63,6 +90,15 @@ class PreProcess : public Gtk::VBox, public AdjusterListener, public ToolPanel{ void darkFrameChanged(); void darkFrameReset(); void dfAutoChanged(); + + void flatFieldFileChanged(); + void flatFieldFile_Reset(); + void flatFieldAutoSelectChanged(); + void flatFieldBlurRadiusChanged(); + void flatFieldBlurTypeChanged(); + + void setDFProvider (DFProvider* p) { dfp = p; }; + void setFFProvider (FFProvider* p) { ffp = p; }; }; #endif diff --git a/rtgui/toolpanelcoord.cc b/rtgui/toolpanelcoord.cc index e53a60ad2..b729869aa 100644 --- a/rtgui/toolpanelcoord.cc +++ b/rtgui/toolpanelcoord.cc @@ -21,6 +21,8 @@ #include #include #include +#include +#include using namespace rtengine::procparams; @@ -136,6 +138,8 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) { whitebalance->setWBProvider (this); whitebalance->setSpotWBListener (this); + preprocess->setDFProvider (this); + preprocess->setFFProvider (this); lensgeom->setLensGeomListener (this); rotate->setLensGeomListener (this); crop->setCropPanelListener (this); @@ -359,6 +363,42 @@ void ToolPanelCoordinator::autoCropRequested () { crop->cropManipReady (); } +rtengine::RawImage* ToolPanelCoordinator::getDF() +{ + if (!ipc) + return NULL; + const rtengine::ImageMetaData *imd = ipc->getInitialImage()->getMetaData(); + if(imd){ + int iso = imd->getISOSpeed(); + double shutter = imd->getShutterSpeed(); + std::string maker( imd->getMake() ); + std::string model( imd->getModel() ); + tm t =imd->getDateTime(); + time_t timestamp = mktime(&t); + + return rtengine::dfm.searchDarkFrame( maker,model,iso,shutter, timestamp); + } + return NULL; +} + +rtengine::RawImage* ToolPanelCoordinator::getFF() +{ + if (!ipc) + return NULL; + const rtengine::ImageMetaData *imd = ipc->getInitialImage()->getMetaData(); + if(imd){ + int iso = imd->getISOSpeed(); + double shutter = imd->getShutterSpeed(); + double aperture = imd->getFNumber(); + std::string maker( imd->getMake() ); + std::string model( imd->getModel() ); + tm t =imd->getDateTime(); + time_t timestamp = mktime(&t); + + return rtengine::ffm.searchFlatField( maker,model,iso,shutter,aperture,timestamp); + } + return NULL; +} void ToolPanelCoordinator::straightenRequested () { if (!ipc) diff --git a/rtgui/toolpanelcoord.h b/rtgui/toolpanelcoord.h index 5fd2d1b53..9f2b09046 100644 --- a/rtgui/toolpanelcoord.h +++ b/rtgui/toolpanelcoord.h @@ -65,6 +65,8 @@ class ImageEditorCoordinator; class ToolPanelCoordinator : public ToolPanelListener, public ProfileChangeListener, public WBProvider, + public DFProvider, + public FFProvider, public LensGeomListener, public SpotWBListener, public CropPanelListener, @@ -91,14 +93,14 @@ class ToolPanelCoordinator : public ToolPanelListener, ShadowsHighlights* shadowshighlights; LumaDenoise* lumadenoise; ColorDenoise* colordenoise; - Defringe* defringe; - ImpulseDenoise* impulsedenoise; - DirPyrDenoise* dirpyrdenoise; + Defringe* defringe; + ImpulseDenoise* impulsedenoise; + DirPyrDenoise* dirpyrdenoise; Sharpening* sharpening; LCurve* lcurve; Equalizer * equalizer; - DirPyrEqualizer * dirpyrequalizer; - HSVEqualizer * hsvequalizer; + DirPyrEqualizer * dirpyrequalizer; + HSVEqualizer * hsvequalizer; RawProcess* rawprocess; PreProcess* preprocess; @@ -159,6 +161,12 @@ class ToolPanelCoordinator : public ToolPanelListener, void getAutoWB (double& temp, double& green) { if (ipc) ipc->getAutoWB (temp, green); } void getCamWB (double& temp, double& green) { if (ipc) ipc->getCamWB (temp, green); } + //DFProvider interface + rtengine::RawImage* getDF(); + + //FFProvider interface + rtengine::RawImage* getFF(); + // rotatelistener interface void straightenRequested (); void autoCropRequested ();