some enhancements of the Fast Export functionality
- remember fast export options across RT sessions - added option to use a dedicated "Fast Export" pipeline, trading speed for quality (resizes early instead of at the end)
This commit is contained in:
@@ -80,6 +80,8 @@ EXPORT_BYPASS_SHARPENEDGE;Bypass Edge Sharpening
|
||||
EXPORT_BYPASS_SHARPENING;Bypass Sharpening
|
||||
EXPORT_BYPASS_SHARPENMICRO;Bypass Microcontrast
|
||||
EXPORT_BYPASS_SH_HQ;Bypass Sharp Mask Shadows/Highlights
|
||||
EXPORT_USE_FAST_PIPELINE;Enable Special "Fast-Export" Processing Pipeline
|
||||
EXPORT_USE_FAST_PIPELINE_TIP;Use a dedicated processing pipeline for images in Fast Export mode, that trades speed for quality. Resizing of the image is done as early as possible, instead of doing it at the end like in the normal pipeline. The speedup can be significant, but be prepared to see artifacts and a general degradation of output quality.
|
||||
EXPORT_FASTEXPORTOPTIONS;<b>Fast Export Options</b>
|
||||
EXPORT_INSTRUCTIONS;Fast Export options provide overrides to bypass time and resource consuming development settings and to run queue processing using the fast export settings instead. This method is recommended for quicker generation of lower resolution images when speed is a priority or when resized output is desired for one or many images without making modifications to their saved development parameters.
|
||||
EXPORT_MAXHEIGHT;Maximum height:
|
||||
|
||||
@@ -49,6 +49,8 @@ public:
|
||||
initialImage->decreaseRef();
|
||||
}
|
||||
}
|
||||
|
||||
bool fastPipeline() const { return fast; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -483,6 +483,8 @@ public:
|
||||
* gets invalid, you must not use it any more. Dont call this function while the job is being processed.
|
||||
* @param job is the job to destroy */
|
||||
static void destroy (ProcessingJob* job);
|
||||
|
||||
virtual bool fastPipeline() const = 0;
|
||||
};
|
||||
|
||||
/** This function performs all the image processinf steps corresponding to the given ProcessingJob. It returns when it is ready, so it can be slow.
|
||||
|
||||
@@ -67,16 +67,12 @@ public:
|
||||
private:
|
||||
Image16 *normal_pipeline()
|
||||
{
|
||||
if (!stage_1()) {
|
||||
if (!stage_init()) {
|
||||
return nullptr;
|
||||
}
|
||||
stage_calc_denoise();
|
||||
stage_2();
|
||||
stage_3();
|
||||
stage_4();
|
||||
stage_5();
|
||||
stage_6();
|
||||
return stage_7();
|
||||
stage_denoise();
|
||||
stage_transform();
|
||||
return stage_finish();
|
||||
}
|
||||
|
||||
Image16 *fast_pipeline()
|
||||
@@ -87,26 +83,16 @@ private:
|
||||
|
||||
pl = nullptr;
|
||||
|
||||
if (!stage_1()) {
|
||||
if (!stage_init()) {
|
||||
return nullptr;
|
||||
}
|
||||
stage_calc_denoise();
|
||||
printf("after calc denoise\n"); fflush(stdout);
|
||||
stage_2();
|
||||
stage_4();
|
||||
printf("after 4\n"); fflush(stdout);
|
||||
stage_transform();
|
||||
stage_early_resize();
|
||||
printf("after early resize\n"); fflush(stdout);
|
||||
stage_3();
|
||||
printf("after 3\n"); fflush(stdout);
|
||||
stage_5();
|
||||
printf("after 5\n"); fflush(stdout);
|
||||
stage_6();
|
||||
printf("after 6\n"); fflush(stdout);
|
||||
return stage_7();
|
||||
stage_denoise();
|
||||
return stage_finish();
|
||||
}
|
||||
|
||||
bool stage_1()
|
||||
bool stage_init()
|
||||
{
|
||||
errorCode = 0;
|
||||
|
||||
@@ -230,19 +216,6 @@ private:
|
||||
currWB.update(rm, gm, bm, params.wb.equal, params.wb.tempBias);
|
||||
}
|
||||
|
||||
// // AG begin
|
||||
// baseImg = new Imagefloat (fw, fh);
|
||||
// imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw);
|
||||
// // AG end
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void stage_calc_denoise()
|
||||
{
|
||||
procparams::ProcParams& params = job->pparams;
|
||||
ImProcFunctions ipf (¶ms, true);
|
||||
|
||||
calclum = nullptr ;
|
||||
params.dirpyrDenoise.getCurves(noiseLCurve, noiseCCurve);
|
||||
autoNR = (float) settings->nrauto;//
|
||||
@@ -713,14 +686,6 @@ private:
|
||||
//end evaluate noise
|
||||
}
|
||||
|
||||
// return true;
|
||||
}
|
||||
|
||||
void stage_2()
|
||||
{
|
||||
procparams::ProcParams& params = job->pparams;
|
||||
ImProcFunctions ipf (¶ms, true);
|
||||
|
||||
baseImg = new Imagefloat (fw, fh);
|
||||
imgsrc->getImage (currWB, tr, baseImg, pp, params.toneCurve, params.icm, params.raw);
|
||||
|
||||
@@ -752,9 +717,11 @@ private:
|
||||
imgsrc->flushRawData();
|
||||
imgsrc->flushRGB();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void stage_3()
|
||||
void stage_denoise()
|
||||
{
|
||||
procparams::ProcParams& params = job->pparams;
|
||||
ImProcFunctions ipf (¶ms, true);
|
||||
@@ -816,17 +783,9 @@ private:
|
||||
delete [] ry;
|
||||
delete [] sk;
|
||||
delete [] pcsk;
|
||||
|
||||
// imgsrc->convertColorSpace(baseImg, params.icm, currWB);
|
||||
|
||||
// // perform first analysis
|
||||
// hist16 (65536);
|
||||
|
||||
// ipf.firstAnalysis (baseImg, params, hist16);
|
||||
}
|
||||
|
||||
|
||||
void stage_4()
|
||||
void stage_transform()
|
||||
{
|
||||
procparams::ProcParams& params = job->pparams;
|
||||
ImProcFunctions ipf (¶ms, true);
|
||||
@@ -848,7 +807,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void stage_5()
|
||||
Image16 *stage_finish()
|
||||
{
|
||||
procparams::ProcParams& params = job->pparams;
|
||||
ImProcFunctions ipf (¶ms, true);
|
||||
@@ -990,13 +949,7 @@ private:
|
||||
if (pl) {
|
||||
pl->setProgress (0.55);
|
||||
}
|
||||
}
|
||||
|
||||
void stage_6()
|
||||
{
|
||||
procparams::ProcParams& params = job->pparams;
|
||||
ImProcFunctions ipf (¶ms, true);
|
||||
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
// start tile processing...???
|
||||
@@ -1187,13 +1140,7 @@ private:
|
||||
if (pl) {
|
||||
pl->setProgress (0.60);
|
||||
}
|
||||
}
|
||||
|
||||
Image16 *stage_7()
|
||||
{
|
||||
procparams::ProcParams& params = job->pparams;
|
||||
ImProcFunctions ipf (¶ms, true);
|
||||
|
||||
int imw, imh;
|
||||
double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh);
|
||||
bool labResize = params.resize.enabled && params.resize.method != "Nearest" && tmpScale != 1.0;
|
||||
@@ -1392,12 +1339,10 @@ private:
|
||||
|
||||
int imw, imh;
|
||||
double tmpScale = ipf.resizeScale(¶ms, fw, fh, imw, imh);
|
||||
// bool resize = params.resize.enabled;
|
||||
|
||||
LabImage *tmplab = new LabImage(fw, fh);
|
||||
ipf.rgb2lab(*baseImg, *tmplab, params.icm.working);
|
||||
|
||||
// crop and convert to rgb16
|
||||
int cx = 0, cy = 0, cw = fw, ch = fh;
|
||||
|
||||
if (params.crop.enabled) {
|
||||
@@ -1438,9 +1383,10 @@ private:
|
||||
params.dirpyrDenoise.luma *= tmpScale;
|
||||
params.dirpyrDenoise.smethod = "shal";
|
||||
|
||||
const double dirpyreq_scale = min(tmpScale * 1.5, 1.0);
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
auto &n = params.dirpyrequalizer.mult[i];
|
||||
n = 1.0 + (n - 1.0) * tmpScale;
|
||||
n = 1.0 + (n - 1.0) * dirpyreq_scale;
|
||||
}
|
||||
|
||||
fw = imw;
|
||||
|
||||
@@ -35,8 +35,6 @@
|
||||
#include "rtimage.h"
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "../rtengine/processingjob.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace rtengine;
|
||||
|
||||
@@ -245,7 +243,7 @@ bool BatchQueue::saveBatchQueue ()
|
||||
<< saveFormat.pngBits << '|' << saveFormat.pngCompression << '|'
|
||||
<< saveFormat.tiffBits << '|' << saveFormat.tiffUncompressed << '|'
|
||||
<< saveFormat.saveParams << '|' << entry->forceFormatOpts << '|'
|
||||
<< static_cast<ProcessingJobImpl *>(entry->job)->fast << '|'
|
||||
<< entry->job->fastPipeline() << '|'
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ ExportPanel::ExportPanel () : listener (nullptr)
|
||||
pack_start(*labExportTitle, Gtk::PACK_SHRINK, 4);
|
||||
|
||||
bypass_ALL = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_ALL")));
|
||||
use_fast_pipeline = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_USE_FAST_PIPELINE")));
|
||||
use_fast_pipeline->set_tooltip_text(M("EXPORT_USE_FAST_PIPELINE_TIP"));
|
||||
bypass_sharpening = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENING")));
|
||||
bypass_sharpenEdge = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENEDGE")));
|
||||
bypass_sharpenMicro = Gtk::manage ( new Gtk::CheckButton (M("EXPORT_BYPASS_SHARPENMICRO")));
|
||||
@@ -96,6 +98,7 @@ ExportPanel::ExportPanel () : listener (nullptr)
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// start global packing
|
||||
pack_start(*use_fast_pipeline , Gtk::PACK_SHRINK, 4);
|
||||
pack_start(*bypass_ALL , Gtk::PACK_SHRINK, 4);
|
||||
pack_start(*Gtk::manage(new Gtk::HSeparator ()), Gtk::PACK_SHRINK, 4);
|
||||
pack_start(*bypass_sharpening , Gtk::PACK_SHRINK, 4);
|
||||
@@ -224,40 +227,48 @@ void ExportPanel::FastExportPressed ()
|
||||
|
||||
void ExportPanel::SaveSettingsAsDefault()
|
||||
{
|
||||
bool changed = false;
|
||||
#define FE_OPT_STORE_(n, v) \
|
||||
do { \
|
||||
if (n != v) { \
|
||||
n = v; \
|
||||
changed = true; \
|
||||
} \
|
||||
} while (false)
|
||||
// Save fast export settings to options
|
||||
options.fastexport_bypass_sharpening = bypass_sharpening->get_active ();
|
||||
options.fastexport_bypass_sharpenEdge = bypass_sharpenEdge->get_active ();
|
||||
options.fastexport_bypass_sharpenMicro = bypass_sharpenMicro->get_active ();
|
||||
FE_OPT_STORE_(options.fastexport_bypass_sharpening, bypass_sharpening->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_sharpenEdge, bypass_sharpenEdge->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_sharpenMicro, bypass_sharpenMicro->get_active ());
|
||||
//options.fastexport_bypass_lumaDenoise = bypass_lumaDenoise->get_active ();
|
||||
//options.fastexport_bypass_colorDenoise = bypass_colorDenoise->get_active ();
|
||||
options.fastexport_bypass_defringe = bypass_defringe->get_active ();
|
||||
options.fastexport_bypass_dirpyrDenoise = bypass_dirpyrDenoise->get_active ();
|
||||
options.fastexport_bypass_sh_hq = bypass_sh_hq->get_active ();
|
||||
options.fastexport_bypass_dirpyrequalizer = bypass_dirpyrequalizer->get_active ();
|
||||
options.fastexport_bypass_wavelet = bypass_wavelet->get_active ();
|
||||
FE_OPT_STORE_(options.fastexport_bypass_defringe, bypass_defringe->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_dirpyrDenoise, bypass_dirpyrDenoise->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_sh_hq, bypass_sh_hq->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_dirpyrequalizer, bypass_dirpyrequalizer->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_wavelet, bypass_wavelet->get_active ());
|
||||
//options.fastexport_bypass_raw_bayer_all_enhance = bypass_raw_all_enhance->get_active ();
|
||||
options.fastexport_bypass_raw_bayer_dcb_iterations = bypass_raw_bayer_dcb_iterations->get_active ();
|
||||
options.fastexport_bypass_raw_bayer_dcb_enhance = bypass_raw_bayer_dcb_enhance->get_active ();
|
||||
options.fastexport_bypass_raw_bayer_lmmse_iterations = bypass_raw_bayer_lmmse_iterations->get_active();
|
||||
options.fastexport_bypass_raw_bayer_linenoise = bypass_raw_bayer_linenoise->get_active ();
|
||||
options.fastexport_bypass_raw_bayer_greenthresh = bypass_raw_bayer_greenthresh->get_active ();
|
||||
options.fastexport_bypass_raw_ccSteps = bypass_raw_ccSteps->get_active ();
|
||||
options.fastexport_bypass_raw_ca = bypass_raw_ca->get_active ();
|
||||
options.fastexport_bypass_raw_df = bypass_raw_df->get_active ();
|
||||
options.fastexport_bypass_raw_ff = bypass_raw_ff->get_active ();
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_dcb_iterations, bypass_raw_bayer_dcb_iterations->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_dcb_enhance, bypass_raw_bayer_dcb_enhance->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_lmmse_iterations, bypass_raw_bayer_lmmse_iterations->get_active());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_linenoise, bypass_raw_bayer_linenoise->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_bayer_greenthresh, bypass_raw_bayer_greenthresh->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_ccSteps, bypass_raw_ccSteps->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_ca, bypass_raw_ca->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_df, bypass_raw_df->get_active ());
|
||||
FE_OPT_STORE_(options.fastexport_bypass_raw_ff, bypass_raw_ff->get_active ());
|
||||
|
||||
//saving Bayer demosaic_method
|
||||
int currentRow = raw_bayer_method->get_active_row_number();
|
||||
|
||||
if( currentRow >= 0 && currentRow < procparams::RAWParams::BayerSensor::numMethods) {
|
||||
options.fastexport_raw_bayer_method = procparams::RAWParams::BayerSensor::methodstring[currentRow];
|
||||
FE_OPT_STORE_(options.fastexport_raw_bayer_method, procparams::RAWParams::BayerSensor::methodstring[currentRow]);
|
||||
}
|
||||
|
||||
//saving X-Trans demosaic_method
|
||||
currentRow = raw_xtrans_method->get_active_row_number();
|
||||
|
||||
if( currentRow >= 0 && currentRow < procparams::RAWParams::XTransSensor::numMethods) {
|
||||
options.fastexport_raw_xtrans_method = procparams::RAWParams::XTransSensor::methodstring[currentRow];
|
||||
FE_OPT_STORE_(options.fastexport_raw_xtrans_method, procparams::RAWParams::XTransSensor::methodstring[currentRow]);
|
||||
}
|
||||
|
||||
// options.fastexport_icm_input = icm_input ;
|
||||
@@ -269,9 +280,16 @@ void ExportPanel::SaveSettingsAsDefault()
|
||||
// options.fastexport_resize_appliesTo = resize_appliesTo;
|
||||
// options.fastexport_resize_dataspec = resize_dataspec ;
|
||||
|
||||
options.fastexport_resize_method = "Lanczos";
|
||||
options.fastexport_resize_width = MaxWidth->get_value_as_int ();
|
||||
options.fastexport_resize_height = MaxHeight->get_value_as_int ();
|
||||
FE_OPT_STORE_(options.fastexport_resize_method, "Lanczos");
|
||||
FE_OPT_STORE_(options.fastexport_resize_width, MaxWidth->get_value_as_int ());
|
||||
FE_OPT_STORE_(options.fastexport_resize_height, MaxHeight->get_value_as_int ());
|
||||
|
||||
FE_OPT_STORE_(options.fastexport_use_fast_pipeline, use_fast_pipeline->get_active());
|
||||
#undef FE_OPT_STORE_
|
||||
|
||||
if (changed) {
|
||||
Options::save();
|
||||
}
|
||||
}
|
||||
|
||||
void ExportPanel::LoadDefaultSettings()
|
||||
@@ -327,6 +345,8 @@ void ExportPanel::LoadDefaultSettings()
|
||||
|
||||
MaxWidth->set_value(options.fastexport_resize_width);
|
||||
MaxHeight->set_value(options.fastexport_resize_height);
|
||||
|
||||
use_fast_pipeline->set_active(options.fastexport_use_fast_pipeline);
|
||||
}
|
||||
|
||||
void ExportPanel::LoadSettings()
|
||||
|
||||
@@ -38,6 +38,7 @@ protected:
|
||||
|
||||
//Gtk::CheckButton* enabled;
|
||||
Gtk::CheckButton* bypass_ALL;
|
||||
Gtk::CheckButton* use_fast_pipeline;
|
||||
Gtk::CheckButton* bypass_sharpenEdge;
|
||||
Gtk::CheckButton* bypass_sharpenMicro;
|
||||
Gtk::CheckButton* bypass_sharpening;
|
||||
|
||||
@@ -1094,7 +1094,7 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
|
||||
// controlling time and resource consuming tasks
|
||||
// and also those which effect is not pronounced after reducing the image size
|
||||
// TODO!!! could expose selections below via preferences
|
||||
if (fastmode && false) {
|
||||
if (fastmode) {
|
||||
if (options.fastexport_bypass_sharpening ) {
|
||||
params.sharpening.enabled = false;
|
||||
}
|
||||
@@ -1183,11 +1183,11 @@ void FileCatalog::developRequested (std::vector<FileBrowserEntry*> tbe, bool fas
|
||||
params.resize.appliesTo = options.fastexport_resize_appliesTo ;
|
||||
params.resize.method = options.fastexport_resize_method ;
|
||||
params.resize.dataspec = options.fastexport_resize_dataspec ;
|
||||
params.resize.width = options.fastexport_resize_width ;
|
||||
params.resize.height = options.fastexport_resize_height ;
|
||||
params.resize.width = rtengine::min(params.resize.width, options.fastexport_resize_width) ;
|
||||
params.resize.height = rtengine::min(params.resize.height, options.fastexport_resize_height) ;
|
||||
}
|
||||
|
||||
rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode);
|
||||
rtengine::ProcessingJob* pjob = rtengine::ProcessingJob::create (fbe->filename, th->getType() == FT_Raw, params, fastmode && options.fastexport_use_fast_pipeline);
|
||||
|
||||
int pw;
|
||||
int ph = BatchQueue::calcMaxThumbnailHeight();
|
||||
|
||||
@@ -480,6 +480,7 @@ void Options::setDefaults ()
|
||||
fastexport_resize_dataspec = 3;
|
||||
fastexport_resize_width = 900;
|
||||
fastexport_resize_height = 900;
|
||||
fastexport_use_fast_pipeline = false;
|
||||
|
||||
clutsDir = "./cluts";
|
||||
|
||||
@@ -1784,6 +1785,9 @@ int Options::readFromFile (Glib::ustring fname)
|
||||
if (keyFile.has_key ("Fast Export", "fastexport_resize_height" )) {
|
||||
fastexport_resize_height = keyFile.get_integer ("Fast Export", "fastexport_resize_height" );
|
||||
}
|
||||
if (keyFile.has_key ("Fast Export", "fastexport_use_fast_pipeline" )) {
|
||||
fastexport_use_fast_pipeline = keyFile.get_integer ("Fast Export", "fastexport_use_fast_pipeline" );
|
||||
}
|
||||
}
|
||||
|
||||
if (keyFile.has_group ("Dialogs")) {
|
||||
@@ -2142,6 +2146,7 @@ int Options::saveToFile (Glib::ustring fname)
|
||||
keyFile.set_integer ("Fast Export", "fastexport_resize_dataspec", fastexport_resize_dataspec );
|
||||
keyFile.set_integer ("Fast Export", "fastexport_resize_width", fastexport_resize_width );
|
||||
keyFile.set_integer ("Fast Export", "fastexport_resize_height", fastexport_resize_height );
|
||||
keyFile.set_integer ("Fast Export", "fastexport_use_fast_pipeline", fastexport_use_fast_pipeline );
|
||||
|
||||
keyFile.set_string ("Dialogs", "LastIccDir", lastIccDir);
|
||||
keyFile.set_string ("Dialogs", "LastDarkframeDir", lastDarkframeDir);
|
||||
|
||||
@@ -279,6 +279,7 @@ public:
|
||||
int fastexport_resize_dataspec;
|
||||
int fastexport_resize_width;
|
||||
int fastexport_resize_height;
|
||||
bool fastexport_use_fast_pipeline;
|
||||
|
||||
// Dialog settings
|
||||
Glib::ustring lastIccDir;
|
||||
|
||||
Reference in New Issue
Block a user