diff --git a/rtdata/languages/default b/rtdata/languages/default
index 6934ec469..f4719f45b 100755
--- a/rtdata/languages/default
+++ b/rtdata/languages/default
@@ -750,6 +750,9 @@ PREFERENCES_CLIPPINGIND;Clipping Indication
PREFERENCES_CMETRICINTENT;Colorimetric intent
PREFERENCES_CUSTPROFBUILDHINT;Executable (or script) file called when a new initial processing profile should be generated for an image.\nReceives command line parameters to allow a rules-based processing profile generation:\n[raw/JPG path] [default processing profile path] [RT's cache folder path] [f-number] [exposure in secs] [focal length in mm] [ISO] [lens] [camera make] [camera model]\n\nWARNING: You are responsible of using double quotes where necessary if you're using paths containing spaces.
PREFERENCES_CUSTPROFBUILDPATH;Executable path
+PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format
+PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID
+PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name
PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder
PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency
PREFERENCES_D50;5000K
diff --git a/rtengine/rtthumbnail.cc b/rtengine/rtthumbnail.cc
index e75e0ba02..8b54c5711 100644
--- a/rtengine/rtthumbnail.cc
+++ b/rtengine/rtthumbnail.cc
@@ -215,6 +215,23 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
#define FISBLUE(filter,row,col) \
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2 || !filter)
+RawMetaDataLocation Thumbnail::loadMetaDataFromRaw (const Glib::ustring& fname)
+{
+ RawMetaDataLocation rml;
+ rml.exifBase = -1;
+ rml.ciffBase = -1;
+ rml.ciffLength = -1;
+
+ RawImage ri(fname);
+ int r = ri.loadRaw(false);
+ if( !r ){
+ rml.exifBase = ri.get_exifBase();
+ rml.ciffBase = ri.get_ciffBase();
+ rml.ciffLength = ri.get_ciffLen();
+ }
+ return rml;
+}
+
Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate)
{
RawImage *ri= new RawImage (fname);
diff --git a/rtengine/rtthumbnail.h b/rtengine/rtthumbnail.h
index fc0219d5f..669b33083 100644
--- a/rtengine/rtthumbnail.h
+++ b/rtengine/rtthumbnail.h
@@ -83,6 +83,7 @@ namespace rtengine {
static Thumbnail* loadQuickFromRaw (const Glib::ustring& fname, rtengine::RawMetaDataLocation& rml, int &w, int &h, int fixwh, bool rotate);
static Thumbnail* loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate);
static Thumbnail* loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq);
+ static RawMetaDataLocation loadMetaDataFromRaw (const Glib::ustring& fname);
void getCamWB (double& temp, double& green);
void getAutoWB (double& temp, double& green, double equal);
diff --git a/rtexif/CMakeLists.txt b/rtexif/CMakeLists.txt
index 6fa05c032..54db707d5 100644
--- a/rtexif/CMakeLists.txt
+++ b/rtexif/CMakeLists.txt
@@ -16,6 +16,8 @@ ELSE (WIN32)
${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS})
ENDIF (WIN32)
+include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}")
+
IF (BUILD_SHARED_LIBS)
INSTALL(TARGETS rtexif DESTINATION ${LIBDIR})
ENDIF (BUILD_SHARED_LIBS)
diff --git a/rtexif/rtexif.cc b/rtexif/rtexif.cc
index 2f376e295..c55779605 100644
--- a/rtexif/rtexif.cc
+++ b/rtexif/rtexif.cc
@@ -25,7 +25,11 @@
#include
#include
+#include "../rtgui/cacheimagedata.h"
#include "rtexif.h"
+#include "../rtengine/safegtk.h"
+#include "../rtgui/version.h"
+#include "../rtgui/ppversion.h"
using namespace std;
@@ -175,6 +179,121 @@ void TagDirectory::printAll (unsigned int level) const {
}
}
+/** @brief Dump the TagDirectory and its sub-directories to the file 'fname'
+ *
+ * This method has been created to dump the metadata for the Custom Profile Builders.
+ * It contains an [RT General] section to communicate some parameters, then the TagDirectory follows.
+ *
+ * The key is composed as follow: "010F_Make", i.e. "tag number or ID _ tag name"
+ * Entries like:
+ *
+ * 927C_MakerNotesSony=$subdir
+ *
+ * indicates that this tag refer to a sub-directory. RT's Keywords begins with $, where & is the first char of the value.
+ * $subdir is the only keyword so far.
+ *
+ * You'll have then to check for the [EXIF/927C_MakerNotesSony] section, given that the root section
+ * is named [EXIF].
+ *
+ * WARNING: Some string will be sanitized, i.e. the new line char will be replaced by "\n". You'll
+ * have to check for this escape string if you want a correct display of the value, but your KeyFile module
+ * will most likely handle that automatically for you.
+ *
+ * @param commFNname Absolute path of the temporary communication file's name
+ * @param commFNname Absolute path of the image's file name
+ * @param commFNname Absolute path of the output profiles's file name
+ * @param defaultPParams absolute or relative path (to the application's folder) of the default ProcParams to use
+ * @param cfs pointer to a CacheImageData object that will contain common values
+ * @param flagMode will tell whether the Custom Profile Builder is called for on flagging event or for real development
+ * @param keyfile The KeyFile object to dump to. Has to be NULL (default value) on first call!
+ * @param tagDirName Name of the current TagDirectory (full path, i.e. "EXIF/MakerNotes/LensInfo"). Can be empty on first call, "EXIF" will then be used
+ *
+ * @return True if everything went fine, false otherwise
+ */
+bool TagDirectory::CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams, const CacheImageData* cfs, const bool flagMode,
+ rtengine::SafeKeyFile *keyFile, Glib::ustring tagDirName) const
+{
+
+ rtengine::SafeKeyFile *kf;
+ if (!keyFile)
+ kf = new rtengine::SafeKeyFile();
+ else
+ kf = keyFile;
+
+ if (!kf)
+ return false;
+
+ if (!keyFile || tagDirName.empty())
+ tagDirName = "EXIF";
+
+ std::vector tagDirList;
+ std::vector tagDirPaths;
+
+ FILE *f;
+ if (!keyFile) {
+ // open the file in write mode
+ f = safe_g_fopen (commFName, "wt");
+ if (f==NULL) {
+ printf("TagDirectory::keyFileDump(\"%s\") >>> Error: unable to open file with write access!\n", commFName.c_str());
+ delete kf;
+ return false;
+ }
+
+ kf->set_string ("RT General", "CachePath", options.cacheBaseDir);
+ kf->set_string ("RT General", "AppVersion", VERSION);
+ kf->set_integer("RT General", "ProcParamsVersion", PPVERSION);
+ kf->set_string ("RT General", "ImageFileName", imageFName);
+ kf->set_string ("RT General", "OutputProfileFileName", profileFName);
+ kf->set_string ("RT General", "DefaultProcParams", defaultPParams);
+ kf->set_boolean("RT General", "FlaggingMode", flagMode);
+
+ kf->set_double ("Common Data", "FNumber", cfs->fnumber);
+ kf->set_double ("Common Data", "Shutter", cfs->shutter);
+ kf->set_double ("Common Data", "FocalLength", cfs->focalLen);
+ kf->set_integer("Common Data", "ISO", cfs->iso);
+ kf->set_string ("Common Data", "Lens", cfs->lens);
+ kf->set_string ("Common Data", "Make", cfs->camMake);
+ kf->set_string ("Common Data", "Model", cfs->camModel);
+ }
+
+ // recursively iterate over the tag list
+ for (size_t i=0; inameToString ();
+ if (tags[i]->isDirectory())
+ for (int j=0; tags[i]->getDirectory(j); j++) {
+ // Accumulating the TagDirectories to dump later
+ tagDirPaths.push_back( Glib::ustring( tagDirName + "/" + getDumpKey(tags[i]->getID(), tagName) ) );
+ tagDirList.push_back(tags[i]->getDirectory(j));
+ kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), "$subdir");
+ }
+ else {
+ kf->set_string (tagDirName, getDumpKey(tags[i]->getID(), tagName), tags[i]->valueToString());
+ }
+ }
+
+ // dumping the sub-directories
+ for (size_t i=0; i< tagDirList.size(); i++)
+ tagDirList.at(i)->CPBDump(commFName, imageFName, profileFName, defaultPParams, cfs, flagMode, kf, tagDirPaths.at(i));
+
+ if (!keyFile) {
+ fprintf (f, "%s", kf->to_data().c_str());
+ fclose (f);
+ delete kf;
+ }
+
+ return true;
+}
+
+Glib::ustring TagDirectory::getDumpKey (int tagID, const Glib::ustring tagName) {
+ Glib::ustring key;
+ if (options.CPBKeys == CPBKT_TID || options.CPBKeys == CPBKT_TID_NAME)
+ key = Glib::ustring(Glib::ustring::format(std::fixed, std::hex, std::setfill(L'0'), std::setw(4), tagID));
+ if (options.CPBKeys == CPBKT_TID_NAME)
+ key += Glib::ustring("_");
+ if (options.CPBKeys == CPBKT_TID_NAME || options.CPBKeys == CPBKT_NAME)
+ key += Glib::ustring(tagName);
+ return key;
+}
void TagDirectory::addTag (Tag* tag) {
// look up if it already exists:
diff --git a/rtexif/rtexif.h b/rtexif/rtexif.h
index b50723256..4dd816186 100644
--- a/rtexif/rtexif.h
+++ b/rtexif/rtexif.h
@@ -28,6 +28,9 @@
#include
#include
#include "../rtengine/procparams.h"
+#include "../rtengine/safekeyfile.h"
+
+class CacheImageData;
namespace rtexif {
@@ -54,7 +57,6 @@ inline void sset4 (int v, unsigned char *s, ByteOrder order);
inline float int_to_float (int i);
short int int2_to_signed (short unsigned int i);
-
struct TIFFHeader {
unsigned short byteOrder;
@@ -92,6 +94,7 @@ class TagDirectory {
const TagAttrib* attribs; // descriptor table to decode the tags
ByteOrder order; // byte order
TagDirectory* parent; // parent directory (NULL if root)
+ static Glib::ustring getDumpKey (int tagID, const Glib::ustring tagName);
public:
TagDirectory ();
@@ -125,7 +128,9 @@ class TagDirectory {
virtual TagDirectory* clone (TagDirectory* parent);
virtual void applyChange (std::string field, std::string value);
- virtual void printAll (unsigned int level=0) const; // reentrant debug function, keep level=0 on first call !
+ virtual void printAll (unsigned int level=0) const; // reentrant debug function, keep level=0 on first call !
+ virtual bool CPBDump (const Glib::ustring &commFName, const Glib::ustring &imageFName, const Glib::ustring &profileFName, const Glib::ustring &defaultPParams,
+ const CacheImageData* cfs, const bool flagMode, rtengine::SafeKeyFile *keyFile=NULL, Glib::ustring tagDirName="") const;
virtual void sort ();
};
diff --git a/rtgui/main.cc b/rtgui/main.cc
index 24b453c7f..de0fdf86f 100644
--- a/rtgui/main.cc
+++ b/rtgui/main.cc
@@ -92,7 +92,7 @@ int main(int argc, char **argv)
setlocale(LC_ALL,"");
// Uncomment the following line if you want to use the "--g-fatal-warnings" command line flag
- //gtk_init (&argc, &argv);
+ gtk_init (&argc, &argv);
Glib::thread_init();
gdk_threads_set_lock_functions(G_CALLBACK(myGdkLockEnter), (G_CALLBACK(myGdkLockLeave)));
diff --git a/rtgui/options.cc b/rtgui/options.cc
index 7e241e3eb..e88db465a 100644
--- a/rtgui/options.cc
+++ b/rtgui/options.cc
@@ -617,16 +617,18 @@ if (keyFile.has_group ("Output")) {
}
if (keyFile.has_group ("Profiles")) {
- if (keyFile.has_key ("Profiles", "Directory")) profilePath = keyFile.get_string ("Profiles", "Directory");
- if (keyFile.has_key ("Profiles", "UseBundledProfiles")) useBundledProfiles = keyFile.get_boolean ("Profiles", "UseBundledProfiles");
- if (keyFile.has_key ("Profiles", "LoadSaveProfilePath")) loadSaveProfilePath = keyFile.get_string ("Profiles", "LoadSaveProfilePath");
- if (keyFile.has_key ("Profiles", "RawDefault")) defProfRaw = keyFile.get_string ("Profiles", "RawDefault");
- if (keyFile.has_key ("Profiles", "ImgDefault")) defProfImg = keyFile.get_string ("Profiles", "ImgDefault");
- if (keyFile.has_key ("Profiles", "FilledProfile")) filledProfile = keyFile.get_boolean ("Profiles", "FilledProfile");
- if (keyFile.has_key ("Profiles", "SaveParamsWithFile")) saveParamsFile = keyFile.get_boolean ("Profiles", "SaveParamsWithFile");
- if (keyFile.has_key ("Profiles", "SaveParamsToCache")) saveParamsCache = keyFile.get_boolean ("Profiles", "SaveParamsToCache");
- if (keyFile.has_key ("Profiles", "LoadParamsFromLocation")) paramsLoadLocation = (PPLoadLocation)keyFile.get_integer ("Profiles", "LoadParamsFromLocation");
- if (keyFile.has_key ("Profiles", "CustomProfileBuilder")) customProfileBuilder = keyFile.get_string ("Profiles", "CustomProfileBuilder");
+ if (keyFile.has_key ("Profiles", "Directory")) profilePath = keyFile.get_string ("Profiles", "Directory");
+ if (keyFile.has_key ("Profiles", "UseBundledProfiles")) useBundledProfiles = keyFile.get_boolean ("Profiles", "UseBundledProfiles");
+ if (keyFile.has_key ("Profiles", "LoadSaveProfilePath")) loadSaveProfilePath = keyFile.get_string ("Profiles", "LoadSaveProfilePath");
+ if (keyFile.has_key ("Profiles", "RawDefault")) defProfRaw = keyFile.get_string ("Profiles", "RawDefault");
+ if (keyFile.has_key ("Profiles", "ImgDefault")) defProfImg = keyFile.get_string ("Profiles", "ImgDefault");
+ if (keyFile.has_key ("Profiles", "FilledProfile")) filledProfile = keyFile.get_boolean ("Profiles", "FilledProfile");
+ if (keyFile.has_key ("Profiles", "SaveParamsWithFile")) saveParamsFile = keyFile.get_boolean ("Profiles", "SaveParamsWithFile");
+ if (keyFile.has_key ("Profiles", "SaveParamsToCache")) saveParamsCache = keyFile.get_boolean ("Profiles", "SaveParamsToCache");
+ if (keyFile.has_key ("Profiles", "LoadParamsFromLocation")) paramsLoadLocation = (PPLoadLocation)keyFile.get_integer ("Profiles", "LoadParamsFromLocation");
+ if (keyFile.has_key ("Profiles", "CustomProfileBuilder")) CPBPath = keyFile.get_string ("Profiles", "CustomProfileBuilder"); // for backward compatibility only
+ if (keyFile.has_key ("Profiles", "CustomProfileBuilderPath")) CPBPath = keyFile.get_string ("Profiles", "CustomProfileBuilderPath");
+ if (keyFile.has_key ("Profiles", "CustomProfileBuilderKeys")) CPBKeys = (CPBKeyType)keyFile.get_integer ("Profiles", "CustomProfileBuilderKeys");
}
if (keyFile.has_group ("File Browser")) {
@@ -948,7 +950,8 @@ int Options::saveToFile (Glib::ustring fname) {
keyFile.set_boolean ("Profiles", "SaveParamsWithFile", saveParamsFile);
keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache);
keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation);
- keyFile.set_string ("Profiles", "CustomProfileBuilder", customProfileBuilder);
+ keyFile.set_string ("Profiles", "CustomProfileBuilderPath", CPBPath);
+ keyFile.set_integer ("Profiles", "CustomProfileBuilderKeys", CPBKeys);
keyFile.set_string ("GUI", "Font", font);
keyFile.set_integer ("GUI", "WindowWidth", windowWidth);
diff --git a/rtgui/options.h b/rtgui/options.h
index 093ce67a2..e77f98e22 100644
--- a/rtgui/options.h
+++ b/rtgui/options.h
@@ -53,6 +53,7 @@ class SaveFormat {
enum ThFileType {FT_Invalid=-1, FT_None=0, FT_Raw=1, FT_Jpeg=2, FT_Tiff=3, FT_Png=4, FT_Custom=5, FT_Tiff16=6, FT_Png16=7, FT_Custom16=8};
enum PPLoadLocation {PLL_Cache=0, PLL_Input=1};
+enum CPBKeyType {CPBKT_TID=0, CPBKT_NAME=1, CPBKT_TID_NAME=2};
namespace rtengine {
class SafeKeyFile;
@@ -155,7 +156,8 @@ class Options {
Glib::ustring gimpDir;
Glib::ustring psDir;
Glib::ustring customEditorProg;
- Glib::ustring customProfileBuilder;
+ Glib::ustring CPBPath; // Custom Profile Builder's path
+ CPBKeyType CPBKeys; // Custom Profile Builder's key type
int editorToSendTo;
int maxThumbnailHeight;
std::size_t maxCacheEntries;
diff --git a/rtgui/preferences.cc b/rtgui/preferences.cc
index b96cdb952..369969dea 100644
--- a/rtgui/preferences.cc
+++ b/rtgui/preferences.cc
@@ -372,6 +372,25 @@ Gtk::Widget* Preferences::getProcParamsPanel () {
fpp->add (*vbpp);
mvbpp->pack_start (*fpp, Gtk::PACK_SHRINK, 4);
+ // Custom profile builder box
+ Gtk::Frame* cpfrm = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CUSTPROFBUILD")) );
+ Gtk::Label* cplab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CUSTPROFBUILDPATH")+":", Gtk::ALIGN_LEFT) );
+ txtCustProfBuilderPath = Gtk::manage( new Gtk::Entry () );
+ txtCustProfBuilderPath->set_tooltip_markup (M("PREFERENCES_CUSTPROFBUILDHINT"));
+ Gtk::Label* cpltypelab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT")+":", Gtk::ALIGN_LEFT) );
+ custProfBuilderLabelType = Gtk::manage (new Gtk::ComboBoxText ());
+ custProfBuilderLabelType->append_text (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID"));
+ custProfBuilderLabelType->append_text (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME"));
+ custProfBuilderLabelType->append_text (M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID") + "_" + M("PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME"));
+ Gtk::Table* cpbt = Gtk::manage (new Gtk::Table (2, 2));
+ cpbt->set_border_width(4);
+ cpbt->attach (*cplab, 0, 1, 0, 1, Gtk::FILL, Gtk::SHRINK, 2, 2);
+ cpbt->attach (*txtCustProfBuilderPath, 1, 2, 0, 1, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
+ cpbt->attach (*cpltypelab, 0, 1, 1, 2, Gtk::FILL, Gtk::SHRINK, 2, 2);
+ cpbt->attach (*custProfBuilderLabelType, 1, 2, 1, 2, Gtk::EXPAND | Gtk::FILL | Gtk::SHRINK, Gtk::SHRINK, 2, 2);
+ cpfrm->add (*cpbt);
+ mvbpp->pack_start (*cpfrm, Gtk::PACK_SHRINK, 4);
+
Gtk::Frame* fdp = Gtk::manage (new Gtk::Frame (M("PREFERENCES_PROFILEHANDLING")));
Gtk::VBox* vbdp = Gtk::manage (new Gtk::VBox ());
vbdp->set_border_width (4);
@@ -812,26 +831,6 @@ Gtk::Widget* Preferences::getGeneralPanel () {
mvbsd->pack_start (*fdg, Gtk::PACK_SHRINK, 4);
- // Custom profile builder box
- Gtk::Frame* cpfrm = Gtk::manage( new Gtk::Frame (M("PREFERENCES_CUSTPROFBUILD")) );
-
- Gtk::HBox* cphb = Gtk::manage( new Gtk::HBox () );
- cphb->set_border_width (4);
- cphb->set_spacing (4);
-
- Gtk::Label* cplab = Gtk::manage( new Gtk::Label (M("PREFERENCES_CUSTPROFBUILDPATH")+":") );
- cphb->pack_start (*cplab, Gtk::PACK_SHRINK,4);
-
- txtCustProfBuilderPath = Gtk::manage( new Gtk::Entry () );
- txtCustProfBuilderPath->set_tooltip_markup (M("PREFERENCES_CUSTPROFBUILDHINT"));
- cphb->set_tooltip_markup (M("PREFERENCES_CUSTPROFBUILDHINT"));
- cphb->pack_start (*txtCustProfBuilderPath);
-
- cpfrm->add (*cphb);
-
- mvbsd->pack_start (*cpfrm, Gtk::PACK_SHRINK, 4);
-
-
mvbsd->set_border_width (4);
tconn = theme->signal_changed().connect( sigc::mem_fun(*this, &Preferences::themeChanged) );
@@ -1143,7 +1142,8 @@ void Preferences::storePreferences () {
else if (edOther->get_active ())
moptions.editorToSendTo = 3;
- moptions.customProfileBuilder = txtCustProfBuilderPath->get_text();
+ moptions.CPBPath = txtCustProfBuilderPath->get_text();
+ moptions.CPBKeys = CPBKeyType(custProfBuilderLabelType->get_active_row_number());
moptions.rtSettings.monitorProfile = monProfile->get_filename ();
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
@@ -1286,7 +1286,9 @@ void Preferences::fillPreferences () {
#endif
editorToSendTo->set_text (moptions.customEditorProg);
- txtCustProfBuilderPath->set_text(moptions.customProfileBuilder);
+ txtCustProfBuilderPath->set_text(moptions.CPBPath);
+ custProfBuilderLabelType->set_active(moptions.CPBKeys);
+
if (moptions.startupDir==STARTUPDIR_CURRENT)
sdcurrent->set_active ();
diff --git a/rtgui/preferences.h b/rtgui/preferences.h
index 0b77b03b0..587682d6b 100644
--- a/rtgui/preferences.h
+++ b/rtgui/preferences.h
@@ -141,6 +141,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener {
Gtk::CheckButton* ckbInternalThumbIfUntouched;
Gtk::Entry* txtCustProfBuilderPath;
+ Gtk::ComboBoxText* custProfBuilderLabelType;
Gtk::CheckButton* ckbHistogramPositionLeft;
Gtk::CheckButton* ckbShowProfileSelector;
diff --git a/rtgui/thumbnail.cc b/rtgui/thumbnail.cc
index ef9475781..e6940ae76 100644
--- a/rtgui/thumbnail.cc
+++ b/rtgui/thumbnail.cc
@@ -191,11 +191,22 @@ const ProcParams& Thumbnail::getProcParamsU () {
return pparams; // there is no valid pp to return, but we have to return something
}
-/*
- * Create default params on demand and returns a new updatable object
+/** @brief Create default params on demand and returns a new updatable object
+ *
* The loaded profile may be partial, but it return a complete ProcParams (i.e. without ParamsEdited)
+ *
+ * @param returnParams Ask to return a pointer to a ProcParams object if true
+ * @param forceCPB True if the Custom Profile Builder has to be invoked, False if the CPB has to be invoked if the profile doesn't
+ * exist yet. It depends on other conditions too
+ * @param flaggingMode True if the ProcParams will be created because the file browser is being flagging an image
+ * (rang, to trash, color labels). This parameter is passed to the CPB.
+ *
+ * @return Return a pointer to a ProcPamas structure to be updated if returnParams is true and if everything went fine, NULL otherwise.
*/
rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool returnParams, bool forceCPB, bool flaggingMode) {
+
+ static int index=0; // Will act as unique identifier during the session
+
// try to load the last saved parameters from the cache or from the paramfile file
ProcParams* ldprof = NULL;
@@ -203,26 +214,44 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu
const CacheImageData* cfs=getCacheImageData();
Glib::ustring defaultPparamsPath = options.findProfilePath(defProf);
- if (!options.customProfileBuilder.empty() && !defaultPparamsPath.empty() && (!hasProcParams() || forceCPB) && cfs && cfs->exifValid) {
- // For the filename etc. do NOT use streams, since they are not UTF8 safe
- Glib::ustring cmdLine = options.customProfileBuilder + Glib::ustring(" \"") + fname + Glib::ustring("\" \"")
- + (defaultPparamsPath == DEFPROFILE_INTERNAL ? "Neutral" : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension)) + Glib::ustring("\" ");
+ if (!options.CPBPath.empty() && !defaultPparamsPath.empty() && (!hasProcParams() || forceCPB) && cfs && cfs->exifValid) {
+ // First generate the communication file, with general values and EXIF metadata
+ rtengine::ImageMetaData* imageMetaData;
+ if (getType()==FT_Raw) {
+ rtengine::RawMetaDataLocation metaData = rtengine::Thumbnail::loadMetaDataFromRaw(fname);
+ imageMetaData = rtengine::ImageMetaData::fromFile (fname, &metaData);
+ }
+ else
+ imageMetaData = rtengine::ImageMetaData::fromFile (fname, NULL);
+
+ Glib::ustring tmpFileName( Glib::build_filename(options.cacheBaseDir, Glib::ustring::compose("CPB_temp_%1.txt", index++)) );
+
+ const rtexif::TagDirectory* exifDir=NULL;
+ if (imageMetaData && (exifDir = imageMetaData->getExifData())) {
+ Glib::ustring outFName;
+ if (options.paramsLoadLocation==PLL_Input)
+ outFName = fname+paramFileExtension;
+ else
+ outFName = getCacheFileName("profiles")+paramFileExtension;
+ exifDir->CPBDump(tmpFileName, fname, outFName,
+ defaultPparamsPath == DEFPROFILE_INTERNAL ? DEFPROFILE_INTERNAL : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension),
+ cfs,
+ flaggingMode);
+ }
+
+ // For the filename etc. do NOT use streams, since they are not UTF8 safe
+ Glib::ustring cmdLine = options.CPBPath + Glib::ustring(" \"") + tmpFileName + Glib::ustring("\" \"");
- // ustring doesn't know int etc formatting, so take these via (unsafe) stream
- std::ostringstream strm;
- strm << Glib::ustring("\"") << options.cacheBaseDir.c_str() << Glib::ustring("\" ");
- strm << flaggingMode << Glib::ustring(" ");
- strm << cfs->fnumber << Glib::ustring(" ") << cfs->shutter << Glib::ustring(" ");
- strm << cfs->focalLen << Glib::ustring(" ") << cfs->iso << Glib::ustring(" \"");
- strm << cfs->lens << Glib::ustring("\" \"") << cfs->camMake << Glib::ustring("\"");
- strm << Glib::ustring(" \"") << cfs->camModel << Glib::ustring("\"");
-
if (options.rtSettings.verbose)
- printf("Custom profile builder's command line: %s\n", Glib::ustring(cmdLine + strm.str()).c_str());
- bool success = safe_spawn_command_line_sync (cmdLine + strm.str());
+ printf("Custom profile builder's command line: %s\n", Glib::ustring(cmdLine).c_str());
+ bool success = safe_spawn_command_line_sync (cmdLine);
// Now they SHOULD be there (and potentially "partial"), so try to load them and store it as a full procparam
if (success) loadProcParams();
+
+ if (safe_file_test(tmpFileName, Glib::FILE_TEST_EXISTS )) safe_g_remove (tmpFileName);
+
+ if (imageMetaData) delete imageMetaData;
}
if (returnParams && hasProcParams()) {
diff --git a/tools/RTProfileBuilderSample.cs b/tools/RTProfileBuilderSample.cs
index 1b0dd028a..20a3b8e1c 100644
--- a/tools/RTProfileBuilderSample.cs
+++ b/tools/RTProfileBuilderSample.cs
@@ -10,8 +10,16 @@ using System.Collections.Specialized;
#endregion
// *** Raw Therapee sample Custom Profile builder (version 2013-08-12) ***
-// WARNING: PP3 format may change in the future versions! If this happens there will probably be no automatic migration path, you'll have to adjust on your own.
-// This is a sample, and therefore not supported by the RT team (just by oduis)
+//
+//
+// WARNING: The command line parameters has changed since this file has been created by Oduis. The new mechanism involves a
+// temporary communication file (.ini style) to provide system parameters and metadata read by RawTherapee. This script has
+// to be updated by some C# developer in order to work.
+//
+//
+// WARNING: PP3 format may change in the future versions! If this happens there will probably be no automatic migration path,
+// you'll have to adjust on your own. This is a sample, and therefore not supported by the RT team (just by oduis)
+//
//
// How to use:
// 1. Modify the GetCorrectedSettings function below according to your needs.