Issue 2047: "One-way communication file between RT and the Custom Profile Builder"
This commit is contained in:
@@ -750,6 +750,9 @@ PREFERENCES_CLIPPINGIND;Clipping Indication
|
|||||||
PREFERENCES_CMETRICINTENT;Colorimetric intent
|
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\n<b>WARNING:</b> You are responsible of using double quotes where necessary if you're using paths containing spaces.
|
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\n<b>WARNING:</b> You are responsible of using double quotes where necessary if you're using paths containing spaces.
|
||||||
PREFERENCES_CUSTPROFBUILDPATH;Executable path
|
PREFERENCES_CUSTPROFBUILDPATH;Executable path
|
||||||
|
PREFERENCES_CUSTPROFBUILDKEYFORMAT;Keys format
|
||||||
|
PREFERENCES_CUSTPROFBUILDKEYFORMAT_TID;TagID
|
||||||
|
PREFERENCES_CUSTPROFBUILDKEYFORMAT_NAME;Name
|
||||||
PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder
|
PREFERENCES_CUSTPROFBUILD;Custom Processing Profile Builder
|
||||||
PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency
|
PREFERENCES_CUTOVERLAYBRUSH;Crop mask color/transparency
|
||||||
PREFERENCES_D50;5000K
|
PREFERENCES_D50;5000K
|
||||||
|
@@ -215,6 +215,23 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
|
|||||||
#define FISBLUE(filter,row,col) \
|
#define FISBLUE(filter,row,col) \
|
||||||
((filter >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)==2 || !filter)
|
((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)
|
Thumbnail* Thumbnail::loadFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, int &w, int &h, int fixwh, double wbEq, bool rotate)
|
||||||
{
|
{
|
||||||
RawImage *ri= new RawImage (fname);
|
RawImage *ri= new RawImage (fname);
|
||||||
|
@@ -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* 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* 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 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 getCamWB (double& temp, double& green);
|
||||||
void getAutoWB (double& temp, double& green, double equal);
|
void getAutoWB (double& temp, double& green, double equal);
|
||||||
|
@@ -16,6 +16,8 @@ ELSE (WIN32)
|
|||||||
${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS})
|
${GLIBMM_LIBRARY_DIRS} ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS})
|
||||||
ENDIF (WIN32)
|
ENDIF (WIN32)
|
||||||
|
|
||||||
|
include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
IF (BUILD_SHARED_LIBS)
|
IF (BUILD_SHARED_LIBS)
|
||||||
INSTALL(TARGETS rtexif DESTINATION ${LIBDIR})
|
INSTALL(TARGETS rtexif DESTINATION ${LIBDIR})
|
||||||
ENDIF (BUILD_SHARED_LIBS)
|
ENDIF (BUILD_SHARED_LIBS)
|
||||||
|
119
rtexif/rtexif.cc
119
rtexif/rtexif.cc
@@ -25,7 +25,11 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "../rtgui/cacheimagedata.h"
|
||||||
#include "rtexif.h"
|
#include "rtexif.h"
|
||||||
|
#include "../rtengine/safegtk.h"
|
||||||
|
#include "../rtgui/version.h"
|
||||||
|
#include "../rtgui/ppversion.h"
|
||||||
|
|
||||||
using namespace std;
|
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<const TagDirectory *> tagDirList;
|
||||||
|
std::vector<Glib::ustring> 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; i<tags.size(); i++) {
|
||||||
|
std::string tagName = tags[i]->nameToString ();
|
||||||
|
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) {
|
void TagDirectory::addTag (Tag* tag) {
|
||||||
|
|
||||||
// look up if it already exists:
|
// look up if it already exists:
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include "../rtengine/procparams.h"
|
#include "../rtengine/procparams.h"
|
||||||
|
#include "../rtengine/safekeyfile.h"
|
||||||
|
|
||||||
|
class CacheImageData;
|
||||||
|
|
||||||
namespace rtexif {
|
namespace rtexif {
|
||||||
|
|
||||||
@@ -54,7 +57,6 @@ inline void sset4 (int v, unsigned char *s, ByteOrder order);
|
|||||||
inline float int_to_float (int i);
|
inline float int_to_float (int i);
|
||||||
short int int2_to_signed (short unsigned int i);
|
short int int2_to_signed (short unsigned int i);
|
||||||
|
|
||||||
|
|
||||||
struct TIFFHeader {
|
struct TIFFHeader {
|
||||||
|
|
||||||
unsigned short byteOrder;
|
unsigned short byteOrder;
|
||||||
@@ -92,6 +94,7 @@ class TagDirectory {
|
|||||||
const TagAttrib* attribs; // descriptor table to decode the tags
|
const TagAttrib* attribs; // descriptor table to decode the tags
|
||||||
ByteOrder order; // byte order
|
ByteOrder order; // byte order
|
||||||
TagDirectory* parent; // parent directory (NULL if root)
|
TagDirectory* parent; // parent directory (NULL if root)
|
||||||
|
static Glib::ustring getDumpKey (int tagID, const Glib::ustring tagName);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TagDirectory ();
|
TagDirectory ();
|
||||||
@@ -125,7 +128,9 @@ class TagDirectory {
|
|||||||
virtual TagDirectory* clone (TagDirectory* parent);
|
virtual TagDirectory* clone (TagDirectory* parent);
|
||||||
virtual void applyChange (std::string field, std::string value);
|
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 ();
|
virtual void sort ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -92,7 +92,7 @@ int main(int argc, char **argv)
|
|||||||
setlocale(LC_ALL,"");
|
setlocale(LC_ALL,"");
|
||||||
|
|
||||||
// Uncomment the following line if you want to use the "--g-fatal-warnings" command line flag
|
// 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();
|
Glib::thread_init();
|
||||||
gdk_threads_set_lock_functions(G_CALLBACK(myGdkLockEnter), (G_CALLBACK(myGdkLockLeave)));
|
gdk_threads_set_lock_functions(G_CALLBACK(myGdkLockEnter), (G_CALLBACK(myGdkLockLeave)));
|
||||||
|
@@ -617,16 +617,18 @@ if (keyFile.has_group ("Output")) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (keyFile.has_group ("Profiles")) {
|
if (keyFile.has_group ("Profiles")) {
|
||||||
if (keyFile.has_key ("Profiles", "Directory")) profilePath = keyFile.get_string ("Profiles", "Directory");
|
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", "UseBundledProfiles")) useBundledProfiles = keyFile.get_boolean ("Profiles", "UseBundledProfiles");
|
||||||
if (keyFile.has_key ("Profiles", "LoadSaveProfilePath")) loadSaveProfilePath = keyFile.get_string ("Profiles", "LoadSaveProfilePath");
|
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", "RawDefault")) defProfRaw = keyFile.get_string ("Profiles", "RawDefault");
|
||||||
if (keyFile.has_key ("Profiles", "ImgDefault")) defProfImg = keyFile.get_string ("Profiles", "ImgDefault");
|
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", "FilledProfile")) filledProfile = keyFile.get_boolean ("Profiles", "FilledProfile");
|
||||||
if (keyFile.has_key ("Profiles", "SaveParamsWithFile")) saveParamsFile = keyFile.get_boolean ("Profiles", "SaveParamsWithFile");
|
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", "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", "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", "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")) {
|
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", "SaveParamsWithFile", saveParamsFile);
|
||||||
keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache);
|
keyFile.set_boolean ("Profiles", "SaveParamsToCache", saveParamsCache);
|
||||||
keyFile.set_integer ("Profiles", "LoadParamsFromLocation", paramsLoadLocation);
|
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_string ("GUI", "Font", font);
|
||||||
keyFile.set_integer ("GUI", "WindowWidth", windowWidth);
|
keyFile.set_integer ("GUI", "WindowWidth", windowWidth);
|
||||||
|
@@ -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 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 PPLoadLocation {PLL_Cache=0, PLL_Input=1};
|
||||||
|
enum CPBKeyType {CPBKT_TID=0, CPBKT_NAME=1, CPBKT_TID_NAME=2};
|
||||||
|
|
||||||
namespace rtengine {
|
namespace rtengine {
|
||||||
class SafeKeyFile;
|
class SafeKeyFile;
|
||||||
@@ -155,7 +156,8 @@ class Options {
|
|||||||
Glib::ustring gimpDir;
|
Glib::ustring gimpDir;
|
||||||
Glib::ustring psDir;
|
Glib::ustring psDir;
|
||||||
Glib::ustring customEditorProg;
|
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 editorToSendTo;
|
||||||
int maxThumbnailHeight;
|
int maxThumbnailHeight;
|
||||||
std::size_t maxCacheEntries;
|
std::size_t maxCacheEntries;
|
||||||
|
@@ -372,6 +372,25 @@ Gtk::Widget* Preferences::getProcParamsPanel () {
|
|||||||
fpp->add (*vbpp);
|
fpp->add (*vbpp);
|
||||||
mvbpp->pack_start (*fpp, Gtk::PACK_SHRINK, 4);
|
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::Frame* fdp = Gtk::manage (new Gtk::Frame (M("PREFERENCES_PROFILEHANDLING")));
|
||||||
Gtk::VBox* vbdp = Gtk::manage (new Gtk::VBox ());
|
Gtk::VBox* vbdp = Gtk::manage (new Gtk::VBox ());
|
||||||
vbdp->set_border_width (4);
|
vbdp->set_border_width (4);
|
||||||
@@ -812,26 +831,6 @@ Gtk::Widget* Preferences::getGeneralPanel () {
|
|||||||
mvbsd->pack_start (*fdg, Gtk::PACK_SHRINK, 4);
|
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);
|
mvbsd->set_border_width (4);
|
||||||
|
|
||||||
tconn = theme->signal_changed().connect( sigc::mem_fun(*this, &Preferences::themeChanged) );
|
tconn = theme->signal_changed().connect( sigc::mem_fun(*this, &Preferences::themeChanged) );
|
||||||
@@ -1143,7 +1142,8 @@ void Preferences::storePreferences () {
|
|||||||
else if (edOther->get_active ())
|
else if (edOther->get_active ())
|
||||||
moptions.editorToSendTo = 3;
|
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.monitorProfile = monProfile->get_filename ();
|
||||||
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
|
moptions.rtSettings.autoMonitorProfile = cbAutoMonProfile->get_active ();
|
||||||
@@ -1286,7 +1286,9 @@ void Preferences::fillPreferences () {
|
|||||||
#endif
|
#endif
|
||||||
editorToSendTo->set_text (moptions.customEditorProg);
|
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)
|
if (moptions.startupDir==STARTUPDIR_CURRENT)
|
||||||
sdcurrent->set_active ();
|
sdcurrent->set_active ();
|
||||||
|
@@ -141,6 +141,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener {
|
|||||||
Gtk::CheckButton* ckbInternalThumbIfUntouched;
|
Gtk::CheckButton* ckbInternalThumbIfUntouched;
|
||||||
|
|
||||||
Gtk::Entry* txtCustProfBuilderPath;
|
Gtk::Entry* txtCustProfBuilderPath;
|
||||||
|
Gtk::ComboBoxText* custProfBuilderLabelType;
|
||||||
|
|
||||||
Gtk::CheckButton* ckbHistogramPositionLeft;
|
Gtk::CheckButton* ckbHistogramPositionLeft;
|
||||||
Gtk::CheckButton* ckbShowProfileSelector;
|
Gtk::CheckButton* ckbShowProfileSelector;
|
||||||
|
@@ -191,11 +191,22 @@ const ProcParams& Thumbnail::getProcParamsU () {
|
|||||||
return pparams; // there is no valid pp to return, but we have to return something
|
return pparams; // there is no valid pp to return, but we have to return something
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/** @brief Create default params on demand and returns a new updatable object
|
||||||
* 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)
|
* 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) {
|
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
|
// try to load the last saved parameters from the cache or from the paramfile file
|
||||||
ProcParams* ldprof = NULL;
|
ProcParams* ldprof = NULL;
|
||||||
|
|
||||||
@@ -203,26 +214,44 @@ rtengine::procparams::ProcParams* Thumbnail::createProcParamsForUpdate(bool retu
|
|||||||
|
|
||||||
const CacheImageData* cfs=getCacheImageData();
|
const CacheImageData* cfs=getCacheImageData();
|
||||||
Glib::ustring defaultPparamsPath = options.findProfilePath(defProf);
|
Glib::ustring defaultPparamsPath = options.findProfilePath(defProf);
|
||||||
if (!options.customProfileBuilder.empty() && !defaultPparamsPath.empty() && (!hasProcParams() || forceCPB) && cfs && cfs->exifValid) {
|
if (!options.CPBPath.empty() && !defaultPparamsPath.empty() && (!hasProcParams() || forceCPB) && cfs && cfs->exifValid) {
|
||||||
// For the filename etc. do NOT use streams, since they are not UTF8 safe
|
// First generate the communication file, with general values and EXIF metadata
|
||||||
Glib::ustring cmdLine = options.customProfileBuilder + Glib::ustring(" \"") + fname + Glib::ustring("\" \"")
|
rtengine::ImageMetaData* imageMetaData;
|
||||||
+ (defaultPparamsPath == DEFPROFILE_INTERNAL ? "Neutral" : Glib::build_filename(defaultPparamsPath, Glib::path_get_basename(defProf) + paramFileExtension)) + Glib::ustring("\" ");
|
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)
|
if (options.rtSettings.verbose)
|
||||||
printf("Custom profile builder's command line: %s\n", Glib::ustring(cmdLine + strm.str()).c_str());
|
printf("Custom profile builder's command line: %s\n", Glib::ustring(cmdLine).c_str());
|
||||||
bool success = safe_spawn_command_line_sync (cmdLine + strm.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
|
// Now they SHOULD be there (and potentially "partial"), so try to load them and store it as a full procparam
|
||||||
if (success) loadProcParams();
|
if (success) loadProcParams();
|
||||||
|
|
||||||
|
if (safe_file_test(tmpFileName, Glib::FILE_TEST_EXISTS )) safe_g_remove (tmpFileName);
|
||||||
|
|
||||||
|
if (imageMetaData) delete imageMetaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (returnParams && hasProcParams()) {
|
if (returnParams && hasProcParams()) {
|
||||||
|
@@ -10,8 +10,16 @@ using System.Collections.Specialized;
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// *** Raw Therapee sample Custom Profile builder (version 2013-08-12) ***
|
// *** 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:
|
// How to use:
|
||||||
// 1. Modify the GetCorrectedSettings function below according to your needs.
|
// 1. Modify the GetCorrectedSettings function below according to your needs.
|
||||||
|
Reference in New Issue
Block a user