feature: added option to use a (fast) neutral RAW rendering in 'inspector mode'

This commit is contained in:
Alberto Griggio 2018-03-21 10:47:38 +01:00
parent 4c3c7a4c09
commit d17bb0cfe6
8 changed files with 139 additions and 12 deletions

View File

@ -1157,6 +1157,10 @@ PREFERENCES_TAB_IMPROC;Image Processing
PREFERENCES_TAB_PERFORMANCE;Performance & Quality PREFERENCES_TAB_PERFORMANCE;Performance & Quality
PREFERENCES_TAB_SOUND;Sounds PREFERENCES_TAB_SOUND;Sounds
PREFERENCES_THEME;Theme PREFERENCES_THEME;Theme
PREFERENCES_THUMBNAIL_INSPECTOR_JPEG;Embedded JPEG preview
PREFERENCES_THUMBNAIL_INSPECTOR_MODE;Image to show
PREFERENCES_THUMBNAIL_INSPECTOR_RAW;Neutral RAW rendering
PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE;Embedded JPEG if fullsize, neutral RAW otherwise
PREFERENCES_TIMAX;High PREFERENCES_TIMAX;High
PREFERENCES_TINB;Number of tiles PREFERENCES_TINB;Number of tiles
PREFERENCES_TISTD;Standard PREFERENCES_TISTD;Standard

View File

@ -1518,7 +1518,7 @@ void RawImageSource::vflip (Imagefloat* image)
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
int RawImageSource::load (const Glib::ustring &fname) int RawImageSource::load (const Glib::ustring &fname, bool firstFrameOnly)
{ {
MyTime t1, t2; MyTime t1, t2;
@ -1535,7 +1535,7 @@ int RawImageSource::load (const Glib::ustring &fname)
if (errCode) { if (errCode) {
return errCode; return errCode;
} }
numFrames = ri->getFrameCount(); numFrames = firstFrameOnly ? 1 : ri->getFrameCount();
errCode = 0; errCode = 0;

View File

@ -118,7 +118,8 @@ public:
RawImageSource (); RawImageSource ();
~RawImageSource (); ~RawImageSource ();
int load (const Glib::ustring &fname); int load(const Glib::ustring &fname) { return load(fname, false); }
int load(const Glib::ustring &fname, bool firstFrameOnly);
void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true); void preprocess (const RAWParams &raw, const LensProfParams &lensProf, const CoarseTransformParams& coarse, bool prepareDenoise = true);
void demosaic (const RAWParams &raw); void demosaic (const RAWParams &raw);
void retinex (const ColorManagementParams& cmp, const RetinexParams &deh, const ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI); void retinex (const ColorManagementParams& cmp, const RetinexParams &deh, const ToneCurveParams& Tc, LUTf & cdcurve, LUTf & mapcurve, const RetinextransmissionCurve & dehatransmissionCurve, const RetinexgaintransmissionCurve & dehagaintransmissionCurve, multi_array2D<float, 4> &conversionBuffer, bool dehacontlutili, bool mapcontlutili, bool useHsl, float &minCD, float &maxCD, float &mini, float &maxi, float &Tmean, float &Tsigma, float &Tmin, float &Tmax, LUTu &histLRETI);

View File

@ -36,7 +36,10 @@
#include "jpeg.h" #include "jpeg.h"
#include "../rtgui/ppversion.h" #include "../rtgui/ppversion.h"
#include "improccoordinator.h" #include "improccoordinator.h"
#include "settings.h"
#include <locale.h> #include <locale.h>
#include "StopWatch.h"
#include "median.h"
namespace namespace
{ {
@ -147,6 +150,8 @@ extern Options options;
namespace rtengine namespace rtengine
{ {
extern const Settings *settings;
using namespace procparams; using namespace procparams;
Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode) Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h, int fixwh, double wbEq, bool inspectorMode)
@ -261,13 +266,92 @@ Thumbnail* Thumbnail::loadFromImage (const Glib::ustring& fname, int &w, int &h,
return tpp; return tpp;
} }
namespace {
Image8 *load_inspector_mode(const Glib::ustring &fname, RawMetaDataLocation &rml, eSensorType &sensorType, int &w, int &h)
{
BENCHFUN
RawImageSource src;
int err = src.load(fname, true);
if (err) {
return nullptr;
}
src.getFullSize(w, h);
sensorType = src.getSensorType();
ProcParams neutral;
neutral.raw.bayersensor.method = RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::FAST);
neutral.raw.xtranssensor.method = RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::FAST);
neutral.icm.input = "(camera)";
neutral.icm.working = "RT_sRGB";
src.preprocess(neutral.raw, neutral.lensProf, neutral.coarse, false);
src.demosaic(neutral.raw);
PreviewProps pp(0, 0, w, h, 1);
Imagefloat tmp(w, h);
src.getImage(src.getWB(), TR_NONE, &tmp, pp, neutral.toneCurve, neutral.raw);
src.convertColorSpace(&tmp, neutral.icm, src.getWB());
Image8 *img = new Image8(w, h);
const float f = 255.f/65535.f;
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
float r = tmp.r(y, x);
float g = tmp.g(y, x);
float b = tmp.b(y, x);
// avoid magenta highlights
if (r > MAXVALF && b > MAXVALF) {
float v = CLIP((r + g + b) / 3.f) * f;
img->r(y, x) = img->g(y, x) = img->b(y, x) = v;
} else {
img->r(y, x) = Color::gamma_srgbclipped(r) * f;
img->g(y, x) = Color::gamma_srgbclipped(g) * f;
img->b(y, x) = Color::gamma_srgbclipped(b) * f;
}
}
}
return img;
}
} // namespace
Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode) Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataLocation& rml, eSensorType &sensorType, int &w, int &h, int fixwh, bool rotate, bool inspectorMode)
{ {
Thumbnail* tpp = new Thumbnail ();
tpp->isRaw = 1;
memset (tpp->colorMatrix, 0, sizeof (tpp->colorMatrix));
tpp->colorMatrix[0][0] = 1.0;
tpp->colorMatrix[1][1] = 1.0;
tpp->colorMatrix[2][2] = 1.0;
if (inspectorMode && !forHistogramMatching && settings->thumbnail_inspector_mode == Settings::ThumbnailInspectorMode::RAW) {
Image8 *img = load_inspector_mode(fname, rml, sensorType, w, h);
if (!img) {
delete tpp;
return nullptr;
}
tpp->scale = 1.;
tpp->thumbImg = img;
return tpp;
}
RawImage *ri = new RawImage (fname); RawImage *ri = new RawImage (fname);
unsigned int imageNum = 0; unsigned int imageNum = 0;
int r = ri->loadRaw (false, imageNum, false); int r = ri->loadRaw (false, imageNum, false);
if ( r ) { if ( r ) {
delete tpp;
delete ri; delete ri;
sensorType = ST_NONE; sensorType = ST_NONE;
return nullptr; return nullptr;
@ -301,24 +385,33 @@ Thumbnail* Thumbnail::loadQuickFromRaw (const Glib::ustring& fname, RawMetaDataL
// did we succeed? // did we succeed?
if ( err ) { if ( err ) {
printf ("Could not extract thumb from %s\n", fname.data()); printf ("Could not extract thumb from %s\n", fname.data());
delete tpp;
delete img; delete img;
delete ri; delete ri;
return nullptr; return nullptr;
} }
Thumbnail* tpp = new Thumbnail ();
tpp->isRaw = 1;
memset (tpp->colorMatrix, 0, sizeof (tpp->colorMatrix));
tpp->colorMatrix[0][0] = 1.0;
tpp->colorMatrix[1][1] = 1.0;
tpp->colorMatrix[2][2] = 1.0;
if (inspectorMode) { if (inspectorMode) {
// Special case, meaning that we want a full sized thumbnail image (e.g. for the Inspector feature) // Special case, meaning that we want a full sized thumbnail image (e.g. for the Inspector feature)
w = img->getWidth(); w = img->getWidth();
h = img->getHeight(); h = img->getHeight();
tpp->scale = 1.; tpp->scale = 1.;
if (!forHistogramMatching && settings->thumbnail_inspector_mode == Settings::ThumbnailInspectorMode::RAW_IF_NOT_JPEG_FULLSIZE && float(std::max(w, h))/float(std::max(ri->get_width(), ri->get_height())) < 0.9f) {
delete img;
delete ri;
img = load_inspector_mode(fname, rml, sensorType, w, h);
if (!img) {
delete tpp;
return nullptr;
}
tpp->scale = 1.;
tpp->thumbImg = img;
return tpp;
}
} else { } else {
if (fixwh == 1) { if (fixwh == 1) {
w = h * img->getWidth() / img->getHeight(); w = h * img->getWidth() / img->getHeight();

View File

@ -83,6 +83,13 @@ public:
double level0_cbdl; double level0_cbdl;
double level123_cbdl; double level123_cbdl;
Glib::ustring lensfunDbDirectory; ///< The directory containing the lensfun database. If empty, the system defaults will be used (as described in http://lensfun.sourceforge.net/manual/dbsearch.html) Glib::ustring lensfunDbDirectory; ///< The directory containing the lensfun database. If empty, the system defaults will be used (as described in http://lensfun.sourceforge.net/manual/dbsearch.html)
enum class ThumbnailInspectorMode {
JPEG,
RAW,
RAW_IF_NOT_JPEG_FULLSIZE
};
ThumbnailInspectorMode thumbnail_inspector_mode;
/** Creates a new instance of Settings. /** Creates a new instance of Settings.
* @return a pointer to the new Settings instance. */ * @return a pointer to the new Settings instance. */

View File

@ -592,6 +592,8 @@ void Options::setDefaults ()
rtSettings.lensfunDbDirectory = ""; // set also in main.cc and main-cli.cc rtSettings.lensfunDbDirectory = ""; // set also in main.cc and main-cli.cc
cropGuides = CROP_GUIDE_FULL; cropGuides = CROP_GUIDE_FULL;
cropAutoFit = false; cropAutoFit = false;
rtSettings.thumbnail_inspector_mode = rtengine::Settings::ThumbnailInspectorMode::JPEG;
} }
Options* Options::copyFrom (Options* other) Options* Options::copyFrom (Options* other)
@ -1065,6 +1067,10 @@ void Options::readFromFile (Glib::ustring fname)
if (keyFile.has_key ("Performance", "SerializeTiffRead")) { if (keyFile.has_key ("Performance", "SerializeTiffRead")) {
serializeTiffRead = keyFile.get_boolean ("Performance", "SerializeTiffRead"); serializeTiffRead = keyFile.get_boolean ("Performance", "SerializeTiffRead");
} }
if (keyFile.has_key("Performance", "ThumbnailInspectorMode")) {
rtSettings.thumbnail_inspector_mode = static_cast<rtengine::Settings::ThumbnailInspectorMode>(keyFile.get_integer("Performance", "ThumbnailInspectorMode"));
}
} }
if (keyFile.has_group ("GUI")) { if (keyFile.has_group ("GUI")) {
@ -1844,6 +1850,7 @@ void Options::saveToFile (Glib::ustring fname)
keyFile.set_integer ("Performance", "PreviewDemosaicFromSidecar", prevdemo); keyFile.set_integer ("Performance", "PreviewDemosaicFromSidecar", prevdemo);
keyFile.set_boolean ("Performance", "Daubechies", rtSettings.daubech); keyFile.set_boolean ("Performance", "Daubechies", rtSettings.daubech);
keyFile.set_boolean ("Performance", "SerializeTiffRead", serializeTiffRead); keyFile.set_boolean ("Performance", "SerializeTiffRead", serializeTiffRead);
keyFile.set_integer("Performance", "ThumbnailInspectorMode", int(rtSettings.thumbnail_inspector_mode));
keyFile.set_string ("Output", "Format", saveFormat.format); keyFile.set_string ("Output", "Format", saveFormat.format);
keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality); keyFile.set_integer ("Output", "JpegQuality", saveFormat.jpegQuality);

View File

@ -657,7 +657,19 @@ Gtk::Widget* Preferences::getPerformancePanel ()
maxInspectorBuffersSB->set_range (1, 12); // ... we have to set a limit, 12 seem to be enough even for systems with tons of RAM maxInspectorBuffersSB->set_range (1, 12); // ... we have to set a limit, 12 seem to be enough even for systems with tons of RAM
maxIBuffersHB->pack_start (*maxIBufferLbl, Gtk::PACK_SHRINK, 0); maxIBuffersHB->pack_start (*maxIBufferLbl, Gtk::PACK_SHRINK, 0);
maxIBuffersHB->pack_end (*maxInspectorBuffersSB, Gtk::PACK_SHRINK, 0); maxIBuffersHB->pack_end (*maxInspectorBuffersSB, Gtk::PACK_SHRINK, 0);
finspect->add (*maxIBuffersHB);
Gtk::VBox *inspectorvb = Gtk::manage(new Gtk::VBox());
inspectorvb->add(*maxIBuffersHB);
Gtk::HBox *insphb = Gtk::manage(new Gtk::HBox());
thumbnailInspectorMode = Gtk::manage(new Gtk::ComboBoxText());
thumbnailInspectorMode->append(M("PREFERENCES_THUMBNAIL_INSPECTOR_JPEG"));
thumbnailInspectorMode->append(M("PREFERENCES_THUMBNAIL_INSPECTOR_RAW"));
thumbnailInspectorMode->append(M("PREFERENCES_THUMBNAIL_INSPECTOR_RAW_IF_NO_JPEG_FULLSIZE"));
insphb->pack_start(*Gtk::manage(new Gtk::Label(M("PREFERENCES_THUMBNAIL_INSPECTOR_MODE") + ": ")), Gtk::PACK_SHRINK, 4);
insphb->pack_start(*thumbnailInspectorMode);
inspectorvb->pack_start(*insphb);
finspect->add (*inspectorvb);
mainContainer->pack_start (*finspect, Gtk::PACK_SHRINK, 4); mainContainer->pack_start (*finspect, Gtk::PACK_SHRINK, 4);
Gtk::Frame* fdenoise = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_NOISE")) ); Gtk::Frame* fdenoise = Gtk::manage ( new Gtk::Frame (M ("PREFERENCES_NOISE")) );
@ -1853,6 +1865,7 @@ void Preferences::storePreferences ()
moptions.rgbDenoiseThreadLimit = rgbDenoiseTreadLimitSB->get_value_as_int(); moptions.rgbDenoiseThreadLimit = rgbDenoiseTreadLimitSB->get_value_as_int();
moptions.clutCacheSize = clutCacheSizeSB->get_value_as_int(); moptions.clutCacheSize = clutCacheSizeSB->get_value_as_int();
moptions.maxInspectorBuffers = maxInspectorBuffersSB->get_value_as_int(); moptions.maxInspectorBuffers = maxInspectorBuffersSB->get_value_as_int();
moptions.rtSettings.thumbnail_inspector_mode = static_cast<rtengine::Settings::ThumbnailInspectorMode>(thumbnailInspectorMode->get_active_row_number());
// Sounds only on Windows and Linux // Sounds only on Windows and Linux
#if defined(WIN32) || defined(__linux__) #if defined(WIN32) || defined(__linux__)
@ -2072,6 +2085,7 @@ void Preferences::fillPreferences ()
rgbDenoiseTreadLimitSB->set_value (moptions.rgbDenoiseThreadLimit); rgbDenoiseTreadLimitSB->set_value (moptions.rgbDenoiseThreadLimit);
clutCacheSizeSB->set_value (moptions.clutCacheSize); clutCacheSizeSB->set_value (moptions.clutCacheSize);
maxInspectorBuffersSB->set_value (moptions.maxInspectorBuffers); maxInspectorBuffersSB->set_value (moptions.maxInspectorBuffers);
thumbnailInspectorMode->set_active(int(moptions.rtSettings.thumbnail_inspector_mode));
darkFrameDir->set_current_folder ( moptions.rtSettings.darkFramesPath ); darkFrameDir->set_current_folder ( moptions.rtSettings.darkFramesPath );
darkFrameChanged (); darkFrameChanged ();

View File

@ -166,6 +166,7 @@ class Preferences : public Gtk::Dialog, public ProfileStoreListener
Gtk::SpinButton* rgbDenoiseTreadLimitSB; Gtk::SpinButton* rgbDenoiseTreadLimitSB;
Gtk::SpinButton* clutCacheSizeSB; Gtk::SpinButton* clutCacheSizeSB;
Gtk::SpinButton* maxInspectorBuffersSB; Gtk::SpinButton* maxInspectorBuffersSB;
Gtk::ComboBoxText *thumbnailInspectorMode;
Gtk::CheckButton* ckbmenuGroupRank; Gtk::CheckButton* ckbmenuGroupRank;
Gtk::CheckButton* ckbmenuGroupLabel; Gtk::CheckButton* ckbmenuGroupLabel;